#include "core/variant.h"
#include "core/io/compression.h"
#include "quickjs_binder.h"
#include "quickjs_builtin_binder.h"

#ifndef inf
#define inf INFINITY
#endif

static JSValue Vector2_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv);
static void bind_Vector2_properties(JSContext *ctx);
static JSValue Rect2_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv);
static void bind_Rect2_properties(JSContext *ctx);
static JSValue Color_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv);
static void bind_Color_properties(JSContext *ctx);
static JSValue Vector3_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv);
static void bind_Vector3_properties(JSContext *ctx);
static JSValue Basis_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv);
static void bind_Basis_properties(JSContext *ctx);
static JSValue Quat_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv);
static void bind_Quat_properties(JSContext *ctx);
static JSValue RID_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv);
static void bind_RID_properties(JSContext *ctx);
static JSValue Transform2D_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv);
static void bind_Transform2D_properties(JSContext *ctx);
static JSValue Plane_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv);
static void bind_Plane_properties(JSContext *ctx);
static JSValue AABB_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv);
static void bind_AABB_properties(JSContext *ctx);
static JSValue Transform_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv);
static void bind_Transform_properties(JSContext *ctx);
static JSValue PoolByteArray_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv);
static void bind_PoolByteArray_properties(JSContext *ctx);
static JSValue PoolIntArray_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv);
static void bind_PoolIntArray_properties(JSContext *ctx);
static JSValue PoolRealArray_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv);
static void bind_PoolRealArray_properties(JSContext *ctx);
static JSValue PoolStringArray_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv);
static void bind_PoolStringArray_properties(JSContext *ctx);
static JSValue PoolVector2Array_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv);
static void bind_PoolVector2Array_properties(JSContext *ctx);
static JSValue PoolVector3Array_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv);
static void bind_PoolVector3Array_properties(JSContext *ctx);
static JSValue PoolColorArray_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv);
static void bind_PoolColorArray_properties(JSContext *ctx);


void QuickJSBuiltinBinder::bind_builtin_classes_gen() {

	register_builtin_class(Variant::VECTOR2, "Vector2", Vector2_constructor, 2);
	bind_Vector2_properties(ctx);
	register_builtin_class(Variant::RECT2, "Rect2", Rect2_constructor, 4);
	bind_Rect2_properties(ctx);
	register_builtin_class(Variant::COLOR, "Color", Color_constructor, 4);
	bind_Color_properties(ctx);
	register_builtin_class(Variant::VECTOR3, "Vector3", Vector3_constructor, 3);
	bind_Vector3_properties(ctx);
	register_builtin_class(Variant::BASIS, "Basis", Basis_constructor, 0);
	bind_Basis_properties(ctx);
	register_builtin_class(Variant::QUAT, "Quat", Quat_constructor, 0);
	bind_Quat_properties(ctx);
	register_builtin_class(Variant::_RID, "RID", RID_constructor, 0);
	bind_RID_properties(ctx);
	register_builtin_class(Variant::TRANSFORM2D, "Transform2D", Transform2D_constructor, 0);
	bind_Transform2D_properties(ctx);
	register_builtin_class(Variant::PLANE, "Plane", Plane_constructor, 0);
	bind_Plane_properties(ctx);
	register_builtin_class(Variant::AABB, "AABB", AABB_constructor, 0);
	bind_AABB_properties(ctx);
	register_builtin_class(Variant::TRANSFORM, "Transform", Transform_constructor, 0);
	bind_Transform_properties(ctx);
	register_builtin_class(Variant::POOL_BYTE_ARRAY, "PoolByteArray", PoolByteArray_constructor, 0);
	bind_PoolByteArray_properties(ctx);
	register_builtin_class(Variant::POOL_INT_ARRAY, "PoolIntArray", PoolIntArray_constructor, 0);
	bind_PoolIntArray_properties(ctx);
	register_builtin_class(Variant::POOL_REAL_ARRAY, "PoolRealArray", PoolRealArray_constructor, 0);
	bind_PoolRealArray_properties(ctx);
	register_builtin_class(Variant::POOL_STRING_ARRAY, "PoolStringArray", PoolStringArray_constructor, 0);
	bind_PoolStringArray_properties(ctx);
	register_builtin_class(Variant::POOL_VECTOR2_ARRAY, "PoolVector2Array", PoolVector2Array_constructor, 0);
	bind_PoolVector2Array_properties(ctx);
	register_builtin_class(Variant::POOL_VECTOR3_ARRAY, "PoolVector3Array", PoolVector3Array_constructor, 0);
	bind_PoolVector3Array_properties(ctx);
	register_builtin_class(Variant::POOL_COLOR_ARRAY, "PoolColorArray", PoolColorArray_constructor, 0);
	bind_PoolColorArray_properties(ctx);

}


static JSValue Vector2_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) {
	Vector2 tmp;
	
	if (argc == 2) {
		tmp.x = QuickJSBinder::js_to_number(ctx, argv[0]);
		tmp.y = QuickJSBinder::js_to_number(ctx, argv[1]);
	} else if (argc == 1) {
		if (ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0])) {
			if (bind->type == Variant::VECTOR2) {
				tmp = *bind->getVector2();
			}
		} else {
			tmp.x = QuickJSBinder::js_to_number(ctx, argv[0]);
			tmp.y = tmp.x;
		}
	}

	JSValue proto = JS_GetProperty(ctx, new_target, QuickJSBinder::JS_ATOM_prototype);
	JSValue obj = JS_NewObjectProtoClass(ctx, proto, QuickJSBinder::get_context_binder(ctx)->get_origin_class_id());
	QuickJSBuiltinBinder::bind_builtin_object(ctx, obj, Variant::VECTOR2, &tmp);
	JS_FreeValue(ctx, proto);
	return obj;
	// return QuickJSBuiltinBinder::create_builtin_value(ctx, Variant::VECTOR2, &tmp);
}

static void bind_Vector2_properties(JSContext *ctx) {
	QuickJSBinder *binder = QuickJSBinder::get_context_binder(ctx);

	JSCFunctionMagic *getter = [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) -> JSValue {
		ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
		const Vector2 *ptr = bind->getVector2();
		switch (magic) {
			case 0:
				return QuickJSBinder::to_js_number(ctx, ptr->x);
			case 1:
				return QuickJSBinder::to_js_number(ctx, ptr->y);
		}
		return JS_UNDEFINED;
	};
	
	JSCFunctionMagic *setter = [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) -> JSValue {
		ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
		Vector2 *ptr = bind->getVector2();
		switch (magic) {
			case 0:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for Vector2.x")));
#endif
				ptr->x = QuickJSBinder::js_to_number(ctx, argv[0]);
				break;
			case 1:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for Vector2.y")));
#endif
				ptr->y = QuickJSBinder::js_to_number(ctx, argv[0]);
				break;
		}
		return JS_DupValue(ctx, argv[0]);
	};
	binder->get_builtin_binder().register_property(Variant::VECTOR2, "x", getter, setter, 0);
	binder->get_builtin_binder().register_property(Variant::VECTOR2, "y", getter, setter, 1);

		
	Vector<JSValue> operators;
	JSValue base_operators = JS_NewObject(ctx);

	JS_SetPropertyStr(ctx, base_operators, "neg",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Vector2 *ptr = bind->getVector2();
			Vector2 ret = ptr->operator-();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"negate",
		1)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "==",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[1]), (JS_ThrowTypeError(ctx, "Vector2 expected for Vector2.operator==")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Vector2 *target = bind1->getVector2();
			bool ret = ptr->operator==(*target);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		"equals",
		2)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "<",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[1]), (JS_ThrowTypeError(ctx, "Vector2 expected for Vector2.operator<")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Vector2 *target = bind1->getVector2();
			bool ret = ptr->operator<(*target);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		"less",
		2)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "+",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[1]), (JS_ThrowTypeError(ctx, "Vector2 expected for Vector2.operator+")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Vector2 *target = bind1->getVector2();
			Vector2 ret = ptr->operator+(*target);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"add",
		2)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "-",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[1]), (JS_ThrowTypeError(ctx, "Vector2 expected for Vector2.operator-")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Vector2 *target = bind1->getVector2();
			Vector2 ret = ptr->operator-(*target);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"subtract",
		2)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "*",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[1]), (JS_ThrowTypeError(ctx, "Vector2 expected for Vector2.operator*")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Vector2 *target = bind1->getVector2();
			Vector2 ret = ptr->operator*(*target);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"multiply",
		2)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "/",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[1]), (JS_ThrowTypeError(ctx, "Vector2 expected for Vector2.operator/")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Vector2 *target = bind1->getVector2();
			Vector2 ret = ptr->operator/(*target);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"multiply",
		2)
	);
	
	operators.push_back(base_operators);
	binder->get_builtin_binder().get_cross_type_operators(Variant::VECTOR2, operators);
	binder->get_builtin_binder().register_operators(Variant::VECTOR2, operators);

	binder->get_builtin_binder().register_constant(Variant::VECTOR2, "AXIS_X", 0);
	binder->get_builtin_binder().register_constant(Variant::VECTOR2, "AXIS_Y", 1);
	binder->get_builtin_binder().register_constant(Variant::VECTOR2, "ZERO", Vector2( 0, 0 ));
	binder->get_builtin_binder().register_constant(Variant::VECTOR2, "ONE", Vector2( 1, 1 ));
	binder->get_builtin_binder().register_constant(Variant::VECTOR2, "INF", Vector2( inf, inf ));
	binder->get_builtin_binder().register_constant(Variant::VECTOR2, "LEFT", Vector2( -1, 0 ));
	binder->get_builtin_binder().register_constant(Variant::VECTOR2, "RIGHT", Vector2( 1, 0 ));
	binder->get_builtin_binder().register_constant(Variant::VECTOR2, "UP", Vector2( 0, -1 ));
	binder->get_builtin_binder().register_constant(Variant::VECTOR2, "DOWN", Vector2( 0, 1 ));


	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"abs",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
			Vector2 ret = ptr->abs();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"angle",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
			real_t ret = ptr->angle();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"angle_to",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Vector2.angle_to")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

			real_t ret = ptr->angle_to(arg0);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"angle_to_point",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Vector2.angle_to_point")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

			real_t ret = ptr->angle_to_point(arg0);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"aspect",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
			real_t ret = ptr->aspect();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"bounce",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Vector2.bounce")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

			Vector2 ret = ptr->bounce(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"ceil",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
			Vector2 ret = ptr->ceil();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"clamped",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of Vector2.clamped")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			Vector2 ret = ptr->clamped(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"cross",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Vector2.cross")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

			real_t ret = ptr->cross(arg0);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"cubic_interpolate",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Vector2.cubic_interpolate")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[1]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 1 of Vector2.cubic_interpolate")));
#endif
			const Vector2 &arg1 = *(BINDING_DATA_FROM_JS(ctx, argv[1]))->getVector2();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[2]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 2 of Vector2.cubic_interpolate")));
#endif
			const Vector2 &arg2 = *(BINDING_DATA_FROM_JS(ctx, argv[2]))->getVector2();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[3]), (JS_ThrowTypeError(ctx, "number expected for argument 3 of Vector2.cubic_interpolate")));
#endif
			const real_t &arg3 = QuickJSBinder::js_to_number(ctx, argv[3]);

			Vector2 ret = ptr->cubic_interpolate(arg0, arg1, arg2, arg3);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		4);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"direction_to",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Vector2.direction_to")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

			Vector2 ret = ptr->direction_to(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"distance_squared_to",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Vector2.distance_squared_to")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

			real_t ret = ptr->distance_squared_to(arg0);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"distance_to",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Vector2.distance_to")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

			real_t ret = ptr->distance_to(arg0);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"dot",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Vector2.dot")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

			real_t ret = ptr->dot(arg0);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"floor",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
			Vector2 ret = ptr->floor();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"is_equal_approx",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Vector2.is_equal_approx")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

			bool ret = ptr->is_equal_approx(arg0);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"is_normalized",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
			bool ret = ptr->is_normalized();
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"length",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
			real_t ret = ptr->length();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"length_squared",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
			real_t ret = ptr->length_squared();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"linear_interpolate",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Vector2.linear_interpolate")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of Vector2.linear_interpolate")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			Vector2 ret = ptr->linear_interpolate(arg0, arg1);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"move_toward",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Vector2.move_toward")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of Vector2.move_toward")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			Vector2 ret = ptr->move_toward(arg0, arg1);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"normalized",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
			Vector2 ret = ptr->normalized();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"posmod",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of Vector2.posmod")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			Vector2 ret = ptr->posmod(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"posmodv",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Vector2.posmodv")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

			Vector2 ret = ptr->posmodv(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"project",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Vector2.project")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

			Vector2 ret = ptr->project(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"reflect",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Vector2.reflect")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

			Vector2 ret = ptr->reflect(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"rotated",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of Vector2.rotated")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			Vector2 ret = ptr->rotated(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"round",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
			Vector2 ret = ptr->round();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"sign",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
			Vector2 ret = ptr->sign();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"slerp",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Vector2.slerp")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of Vector2.slerp")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			Vector2 ret = ptr->slerp(arg0, arg1);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"slide",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Vector2.slide")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

			Vector2 ret = ptr->slide(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"snapped",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Vector2.snapped")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

			Vector2 ret = ptr->snapped(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR2,
		"tangent",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector2 *ptr = bind->getVector2();
			Vector2 ret = ptr->tangent();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
}

static JSValue Rect2_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) {
	Rect2 tmp;
	
	if (argc == 4) {
		tmp.position.x = QuickJSBinder::js_to_number(ctx, argv[0]);
		tmp.position.y = QuickJSBinder::js_to_number(ctx, argv[1]);
		tmp.size.x = QuickJSBinder::js_to_number(ctx, argv[2]);
		tmp.size.y = QuickJSBinder::js_to_number(ctx, argv[3]);
	} else if (argc == 2) {
#ifdef DEBUG_METHODS_ENABLED
		ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Rect2(position, size)")));
		ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[1]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 1 of Rect2(position, size)")));
#endif
		ECMAScriptGCHandler *param0 = BINDING_DATA_FROM_JS(ctx, argv[0]);
		ECMAScriptGCHandler *param1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
		tmp.position = *param0->getVector2();
		tmp.size = *param1->getVector2();
	} else if (argc == 1) {
		if (ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0])) {
			if (bind->type == Variant::RECT2)
				tmp = *bind->getRect2();
		}
	}

	JSValue proto = JS_GetProperty(ctx, new_target, QuickJSBinder::JS_ATOM_prototype);
	JSValue obj = JS_NewObjectProtoClass(ctx, proto, QuickJSBinder::get_context_binder(ctx)->get_origin_class_id());
	QuickJSBuiltinBinder::bind_builtin_object(ctx, obj, Variant::RECT2, &tmp);
	JS_FreeValue(ctx, proto);
	return obj;
	// return QuickJSBuiltinBinder::create_builtin_value(ctx, Variant::RECT2, &tmp);
}

static void bind_Rect2_properties(JSContext *ctx) {
	QuickJSBinder *binder = QuickJSBinder::get_context_binder(ctx);

	JSCFunctionMagic *getter = [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) -> JSValue {
		ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
		const Rect2 *ptr = bind->getRect2();
		switch (magic) {
			case 0:
				return QuickJSBuiltinBinder::new_object_from(ctx, ptr->position);
			case 1:
				return QuickJSBuiltinBinder::new_object_from(ctx, ptr->size);
		}
		return JS_UNDEFINED;
	};
	
	JSCFunctionMagic *setter = [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) -> JSValue {
		ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
		Rect2 *ptr = bind->getRect2();
		switch (magic) {
			case 0:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for Rect2.position")));
#endif
				ptr->position = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();
				break;
			case 1:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for Rect2.size")));
#endif
				ptr->size = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();
				break;
		}
		return JS_DupValue(ctx, argv[0]);
	};
	binder->get_builtin_binder().register_property(Variant::RECT2, "position", getter, setter, 0);
	binder->get_builtin_binder().register_property(Variant::RECT2, "size", getter, setter, 1);

		
	Vector<JSValue> operators;
	JSValue base_operators = JS_NewObject(ctx);

	JS_SetPropertyStr(ctx, base_operators, "==",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Rect2 *ptr = bind->getRect2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::RECT2, argv[1]), (JS_ThrowTypeError(ctx, "Rect2 expected for Rect2.operator==")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Rect2 *target = bind1->getRect2();
			bool ret = ptr->operator==(*target);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		"equals",
		2)
	);
	
	operators.push_back(base_operators);
	binder->get_builtin_binder().get_cross_type_operators(Variant::RECT2, operators);
	binder->get_builtin_binder().register_operators(Variant::RECT2, operators);



	binder->get_builtin_binder().register_method(
		Variant::RECT2,
		"abs",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Rect2 *ptr = bind->getRect2();
			Rect2 ret = ptr->abs();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::RECT2,
		"clip",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Rect2 *ptr = bind->getRect2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::RECT2, argv[0]), (JS_ThrowTypeError(ctx, "Rect2 expected for argument 0 of Rect2.clip")));
#endif
			const Rect2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getRect2();

			Rect2 ret = ptr->clip(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::RECT2,
		"encloses",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Rect2 *ptr = bind->getRect2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::RECT2, argv[0]), (JS_ThrowTypeError(ctx, "Rect2 expected for argument 0 of Rect2.encloses")));
#endif
			const Rect2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getRect2();

			bool ret = ptr->encloses(arg0);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::RECT2,
		"expand",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Rect2 *ptr = bind->getRect2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Rect2.expand")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

			Rect2 ret = ptr->expand(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::RECT2,
		"get_area",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Rect2 *ptr = bind->getRect2();
			real_t ret = ptr->get_area();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::RECT2,
		"grow",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Rect2 *ptr = bind->getRect2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of Rect2.grow")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			Rect2 ret = ptr->grow(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::RECT2,
		"grow_individual",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Rect2 *ptr = bind->getRect2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of Rect2.grow_individual")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of Rect2.grow_individual")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[2]), (JS_ThrowTypeError(ctx, "number expected for argument 2 of Rect2.grow_individual")));
#endif
			const real_t &arg2 = QuickJSBinder::js_to_number(ctx, argv[2]);

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[3]), (JS_ThrowTypeError(ctx, "number expected for argument 3 of Rect2.grow_individual")));
#endif
			const real_t &arg3 = QuickJSBinder::js_to_number(ctx, argv[3]);

			Rect2 ret = ptr->grow_individual(arg0, arg1, arg2, arg3);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		4);
	binder->get_builtin_binder().register_method(
		Variant::RECT2,
		"has_no_area",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Rect2 *ptr = bind->getRect2();
			bool ret = ptr->has_no_area();
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::RECT2,
		"has_point",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Rect2 *ptr = bind->getRect2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Rect2.has_point")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

			bool ret = ptr->has_point(arg0);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::RECT2,
		"intersects",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Rect2 *ptr = bind->getRect2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::RECT2, argv[0]), (JS_ThrowTypeError(ctx, "Rect2 expected for argument 0 of Rect2.intersects")));
#endif
			const Rect2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getRect2();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::BOOL, argv[1]), (JS_ThrowTypeError(ctx, "boolean expected for argument 1 of Rect2.intersects")));
#endif
			const bool &arg1 = QuickJSBinder::js_to_bool(ctx, argv[1]);

			bool ret = ptr->intersects(arg0, arg1);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::RECT2,
		"is_equal_approx",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Rect2 *ptr = bind->getRect2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::RECT2, argv[0]), (JS_ThrowTypeError(ctx, "Rect2 expected for argument 0 of Rect2.is_equal_approx")));
#endif
			const Rect2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getRect2();

			bool ret = ptr->is_equal_approx(arg0);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::RECT2,
		"merge",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Rect2 *ptr = bind->getRect2();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::RECT2, argv[0]), (JS_ThrowTypeError(ctx, "Rect2 expected for argument 0 of Rect2.merge")));
#endif
			const Rect2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getRect2();

			Rect2 ret = ptr->merge(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
}

static JSValue Color_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) {
	Color tmp;
	
	if (argc >= 3) {
		tmp.r = QuickJSBinder::js_to_number(ctx, argv[0]);
		tmp.g = QuickJSBinder::js_to_number(ctx, argv[1]);
		tmp.b = QuickJSBinder::js_to_number(ctx, argv[2]);
		tmp.a = (argc >= 4) ? QuickJSBinder::js_to_number(ctx, argv[3]) : 1.0f;
	} else if (argc == 1) {
		if (JS_IsNumber(argv[0])) {
			tmp = Color::hex(QuickJSBinder::js_to_uint(ctx, argv[0]));
		} else if (JS_IsString(argv[0])) {
			tmp = Color::html(QuickJSBinder::js_to_string(ctx, argv[0]));
		} else if (ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0])) {
			if (bind->type == Variant::COLOR) {
				tmp = *bind->getColor();
			}
		}
	}

	JSValue proto = JS_GetProperty(ctx, new_target, QuickJSBinder::JS_ATOM_prototype);
	JSValue obj = JS_NewObjectProtoClass(ctx, proto, QuickJSBinder::get_context_binder(ctx)->get_origin_class_id());
	QuickJSBuiltinBinder::bind_builtin_object(ctx, obj, Variant::COLOR, &tmp);
	JS_FreeValue(ctx, proto);
	return obj;
	// return QuickJSBuiltinBinder::create_builtin_value(ctx, Variant::COLOR, &tmp);
}

static void bind_Color_properties(JSContext *ctx) {
	QuickJSBinder *binder = QuickJSBinder::get_context_binder(ctx);

	JSCFunctionMagic *getter = [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) -> JSValue {
		ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
		const Color *ptr = bind->getColor();
		switch (magic) {
			case 0:
				return QuickJSBinder::to_js_number(ctx, ptr->a);
			case 1:
				return QuickJSBinder::to_js_number(ctx, ptr->b);
			case 2:
				return QuickJSBinder::to_js_number(ctx, ptr->g);
			case 3:
				return QuickJSBinder::to_js_number(ctx, ptr->r);
		}
		return JS_UNDEFINED;
	};
	
	JSCFunctionMagic *setter = [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) -> JSValue {
		ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
		Color *ptr = bind->getColor();
		switch (magic) {
			case 0:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for Color.a")));
#endif
				ptr->a = QuickJSBinder::js_to_number(ctx, argv[0]);
				break;
			case 1:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for Color.b")));
#endif
				ptr->b = QuickJSBinder::js_to_number(ctx, argv[0]);
				break;
			case 2:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for Color.g")));
#endif
				ptr->g = QuickJSBinder::js_to_number(ctx, argv[0]);
				break;
			case 3:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for Color.r")));
#endif
				ptr->r = QuickJSBinder::js_to_number(ctx, argv[0]);
				break;
		}
		return JS_DupValue(ctx, argv[0]);
	};
	binder->get_builtin_binder().register_property(Variant::COLOR, "a", getter, setter, 0);
	binder->get_builtin_binder().register_property(Variant::COLOR, "b", getter, setter, 1);
	binder->get_builtin_binder().register_property(Variant::COLOR, "g", getter, setter, 2);
	binder->get_builtin_binder().register_property(Variant::COLOR, "r", getter, setter, 3);

		
	Vector<JSValue> operators;
	JSValue base_operators = JS_NewObject(ctx);

	JS_SetPropertyStr(ctx, base_operators, "neg",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Color *ptr = bind->getColor();
			Color ret = ptr->operator-();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"negate",
		1)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "==",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Color *ptr = bind->getColor();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::COLOR, argv[1]), (JS_ThrowTypeError(ctx, "Color expected for Color.operator==")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Color *target = bind1->getColor();
			bool ret = ptr->operator==(*target);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		"equals",
		2)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "<",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Color *ptr = bind->getColor();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::COLOR, argv[1]), (JS_ThrowTypeError(ctx, "Color expected for Color.operator<")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Color *target = bind1->getColor();
			bool ret = ptr->operator<(*target);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		"less",
		2)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "+",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Color *ptr = bind->getColor();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::COLOR, argv[1]), (JS_ThrowTypeError(ctx, "Color expected for Color.operator+")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Color *target = bind1->getColor();
			Color ret = ptr->operator+(*target);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"add",
		2)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "-",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Color *ptr = bind->getColor();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::COLOR, argv[1]), (JS_ThrowTypeError(ctx, "Color expected for Color.operator-")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Color *target = bind1->getColor();
			Color ret = ptr->operator-(*target);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"subtract",
		2)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "*",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Color *ptr = bind->getColor();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::COLOR, argv[1]), (JS_ThrowTypeError(ctx, "Color expected for Color.operator*")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Color *target = bind1->getColor();
			Color ret = ptr->operator*(*target);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"multiply",
		2)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "/",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Color *ptr = bind->getColor();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::COLOR, argv[1]), (JS_ThrowTypeError(ctx, "Color expected for Color.operator/")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Color *target = bind1->getColor();
			Color ret = ptr->operator/(*target);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"multiply",
		2)
	);
	
	operators.push_back(base_operators);
	binder->get_builtin_binder().get_cross_type_operators(Variant::COLOR, operators);
	binder->get_builtin_binder().register_operators(Variant::COLOR, operators);

	binder->get_builtin_binder().register_constant(Variant::COLOR, "aliceblue", Color( 0.94, 0.97, 1, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "antiquewhite", Color( 0.98, 0.92, 0.84, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "aqua", Color( 0, 1, 1, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "aquamarine", Color( 0.5, 1, 0.83, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "azure", Color( 0.94, 1, 1, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "beige", Color( 0.96, 0.96, 0.86, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "bisque", Color( 1, 0.89, 0.77, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "black", Color( 0, 0, 0, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "blanchedalmond", Color( 1, 0.92, 0.8, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "blue", Color( 0, 0, 1, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "blueviolet", Color( 0.54, 0.17, 0.89, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "brown", Color( 0.65, 0.16, 0.16, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "burlywood", Color( 0.87, 0.72, 0.53, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "cadetblue", Color( 0.37, 0.62, 0.63, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "chartreuse", Color( 0.5, 1, 0, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "chocolate", Color( 0.82, 0.41, 0.12, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "coral", Color( 1, 0.5, 0.31, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "cornflower", Color( 0.39, 0.58, 0.93, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "cornsilk", Color( 1, 0.97, 0.86, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "crimson", Color( 0.86, 0.08, 0.24, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "cyan", Color( 0, 1, 1, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "darkblue", Color( 0, 0, 0.55, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "darkcyan", Color( 0, 0.55, 0.55, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "darkgoldenrod", Color( 0.72, 0.53, 0.04, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "darkgray", Color( 0.66, 0.66, 0.66, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "darkgreen", Color( 0, 0.39, 0, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "darkkhaki", Color( 0.74, 0.72, 0.42, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "darkmagenta", Color( 0.55, 0, 0.55, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "darkolivegreen", Color( 0.33, 0.42, 0.18, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "darkorange", Color( 1, 0.55, 0, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "darkorchid", Color( 0.6, 0.2, 0.8, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "darkred", Color( 0.55, 0, 0, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "darksalmon", Color( 0.91, 0.59, 0.48, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "darkseagreen", Color( 0.56, 0.74, 0.56, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "darkslateblue", Color( 0.28, 0.24, 0.55, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "darkslategray", Color( 0.18, 0.31, 0.31, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "darkturquoise", Color( 0, 0.81, 0.82, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "darkviolet", Color( 0.58, 0, 0.83, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "deeppink", Color( 1, 0.08, 0.58, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "deepskyblue", Color( 0, 0.75, 1, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "dimgray", Color( 0.41, 0.41, 0.41, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "dodgerblue", Color( 0.12, 0.56, 1, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "firebrick", Color( 0.7, 0.13, 0.13, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "floralwhite", Color( 1, 0.98, 0.94, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "forestgreen", Color( 0.13, 0.55, 0.13, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "fuchsia", Color( 1, 0, 1, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "gainsboro", Color( 0.86, 0.86, 0.86, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "ghostwhite", Color( 0.97, 0.97, 1, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "gold", Color( 1, 0.84, 0, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "goldenrod", Color( 0.85, 0.65, 0.13, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "gray", Color( 0.75, 0.75, 0.75, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "green", Color( 0, 1, 0, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "greenyellow", Color( 0.68, 1, 0.18, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "honeydew", Color( 0.94, 1, 0.94, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "hotpink", Color( 1, 0.41, 0.71, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "indianred", Color( 0.8, 0.36, 0.36, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "indigo", Color( 0.29, 0, 0.51, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "ivory", Color( 1, 1, 0.94, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "khaki", Color( 0.94, 0.9, 0.55, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "lavender", Color( 0.9, 0.9, 0.98, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "lavenderblush", Color( 1, 0.94, 0.96, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "lawngreen", Color( 0.49, 0.99, 0, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "lemonchiffon", Color( 1, 0.98, 0.8, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "lightblue", Color( 0.68, 0.85, 0.9, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "lightcoral", Color( 0.94, 0.5, 0.5, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "lightcyan", Color( 0.88, 1, 1, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "lightgoldenrod", Color( 0.98, 0.98, 0.82, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "lightgray", Color( 0.83, 0.83, 0.83, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "lightgreen", Color( 0.56, 0.93, 0.56, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "lightpink", Color( 1, 0.71, 0.76, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "lightsalmon", Color( 1, 0.63, 0.48, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "lightseagreen", Color( 0.13, 0.7, 0.67, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "lightskyblue", Color( 0.53, 0.81, 0.98, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "lightslategray", Color( 0.47, 0.53, 0.6, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "lightsteelblue", Color( 0.69, 0.77, 0.87, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "lightyellow", Color( 1, 1, 0.88, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "lime", Color( 0, 1, 0, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "limegreen", Color( 0.2, 0.8, 0.2, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "linen", Color( 0.98, 0.94, 0.9, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "magenta", Color( 1, 0, 1, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "maroon", Color( 0.69, 0.19, 0.38, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "mediumaquamarine", Color( 0.4, 0.8, 0.67, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "mediumblue", Color( 0, 0, 0.8, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "mediumorchid", Color( 0.73, 0.33, 0.83, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "mediumpurple", Color( 0.58, 0.44, 0.86, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "mediumseagreen", Color( 0.24, 0.7, 0.44, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "mediumslateblue", Color( 0.48, 0.41, 0.93, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "mediumspringgreen", Color( 0, 0.98, 0.6, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "mediumturquoise", Color( 0.28, 0.82, 0.8, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "mediumvioletred", Color( 0.78, 0.08, 0.52, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "midnightblue", Color( 0.1, 0.1, 0.44, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "mintcream", Color( 0.96, 1, 0.98, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "mistyrose", Color( 1, 0.89, 0.88, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "moccasin", Color( 1, 0.89, 0.71, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "navajowhite", Color( 1, 0.87, 0.68, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "navyblue", Color( 0, 0, 0.5, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "oldlace", Color( 0.99, 0.96, 0.9, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "olive", Color( 0.5, 0.5, 0, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "olivedrab", Color( 0.42, 0.56, 0.14, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "orange", Color( 1, 0.65, 0, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "orangered", Color( 1, 0.27, 0, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "orchid", Color( 0.85, 0.44, 0.84, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "palegoldenrod", Color( 0.93, 0.91, 0.67, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "palegreen", Color( 0.6, 0.98, 0.6, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "paleturquoise", Color( 0.69, 0.93, 0.93, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "palevioletred", Color( 0.86, 0.44, 0.58, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "papayawhip", Color( 1, 0.94, 0.84, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "peachpuff", Color( 1, 0.85, 0.73, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "peru", Color( 0.8, 0.52, 0.25, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "pink", Color( 1, 0.75, 0.8, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "plum", Color( 0.87, 0.63, 0.87, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "powderblue", Color( 0.69, 0.88, 0.9, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "purple", Color( 0.63, 0.13, 0.94, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "rebeccapurple", Color( 0.4, 0.2, 0.6, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "red", Color( 1, 0, 0, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "rosybrown", Color( 0.74, 0.56, 0.56, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "royalblue", Color( 0.25, 0.41, 0.88, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "saddlebrown", Color( 0.55, 0.27, 0.07, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "salmon", Color( 0.98, 0.5, 0.45, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "sandybrown", Color( 0.96, 0.64, 0.38, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "seagreen", Color( 0.18, 0.55, 0.34, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "seashell", Color( 1, 0.96, 0.93, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "sienna", Color( 0.63, 0.32, 0.18, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "silver", Color( 0.75, 0.75, 0.75, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "skyblue", Color( 0.53, 0.81, 0.92, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "slateblue", Color( 0.42, 0.35, 0.8, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "slategray", Color( 0.44, 0.5, 0.56, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "snow", Color( 1, 0.98, 0.98, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "springgreen", Color( 0, 1, 0.5, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "steelblue", Color( 0.27, 0.51, 0.71, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "tan", Color( 0.82, 0.71, 0.55, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "teal", Color( 0, 0.5, 0.5, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "thistle", Color( 0.85, 0.75, 0.85, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "tomato", Color( 1, 0.39, 0.28, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "transparent", Color( 1, 1, 1, 0 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "turquoise", Color( 0.25, 0.88, 0.82, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "violet", Color( 0.93, 0.51, 0.93, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "webgray", Color( 0.5, 0.5, 0.5, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "webgreen", Color( 0, 0.5, 0, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "webmaroon", Color( 0.5, 0, 0, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "webpurple", Color( 0.5, 0, 0.5, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "wheat", Color( 0.96, 0.87, 0.7, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "white", Color( 1, 1, 1, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "whitesmoke", Color( 0.96, 0.96, 0.96, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "yellow", Color( 1, 1, 0, 1 ));
	binder->get_builtin_binder().register_constant(Variant::COLOR, "yellowgreen", Color( 0.6, 0.8, 0.2, 1 ));


	binder->get_builtin_binder().register_method(
		Variant::COLOR,
		"blend",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Color *ptr = bind->getColor();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::COLOR, argv[0]), (JS_ThrowTypeError(ctx, "Color expected for argument 0 of Color.blend")));
#endif
			const Color &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getColor();

			Color ret = ptr->blend(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::COLOR,
		"contrasted",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Color *ptr = bind->getColor();
			Color ret = ptr->contrasted();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::COLOR,
		"darkened",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Color *ptr = bind->getColor();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of Color.darkened")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			Color ret = ptr->darkened(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::COLOR,
		"from_hsv",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Color *ptr = bind->getColor();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of Color.from_hsv")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of Color.from_hsv")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[2]), (JS_ThrowTypeError(ctx, "number expected for argument 2 of Color.from_hsv")));
#endif
			const real_t &arg2 = QuickJSBinder::js_to_number(ctx, argv[2]);

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[3]), (JS_ThrowTypeError(ctx, "number expected for argument 3 of Color.from_hsv")));
#endif
			const real_t &arg3 = QuickJSBinder::js_to_number(ctx, argv[3]);

			Color ret = ptr->from_hsv(arg0, arg1, arg2, arg3);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		4);
	binder->get_builtin_binder().register_method(
		Variant::COLOR,
		"gray",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Color *ptr = bind->getColor();
			real_t ret = ptr->gray();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::COLOR,
		"inverted",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Color *ptr = bind->getColor();
			Color ret = ptr->inverted();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::COLOR,
		"is_equal_approx",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Color *ptr = bind->getColor();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::COLOR, argv[0]), (JS_ThrowTypeError(ctx, "Color expected for argument 0 of Color.is_equal_approx")));
#endif
			const Color &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getColor();

			bool ret = ptr->is_equal_approx(arg0);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::COLOR,
		"lightened",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Color *ptr = bind->getColor();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of Color.lightened")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			Color ret = ptr->lightened(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::COLOR,
		"linear_interpolate",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Color *ptr = bind->getColor();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::COLOR, argv[0]), (JS_ThrowTypeError(ctx, "Color expected for argument 0 of Color.linear_interpolate")));
#endif
			const Color &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getColor();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of Color.linear_interpolate")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			Color ret = ptr->linear_interpolate(arg0, arg1);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::COLOR,
		"to_abgr32",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Color *ptr = bind->getColor();
			real_t ret = ptr->to_abgr32();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::COLOR,
		"to_abgr64",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Color *ptr = bind->getColor();
			real_t ret = ptr->to_abgr64();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::COLOR,
		"to_argb32",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Color *ptr = bind->getColor();
			real_t ret = ptr->to_argb32();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::COLOR,
		"to_argb64",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Color *ptr = bind->getColor();
			real_t ret = ptr->to_argb64();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::COLOR,
		"to_html",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Color *ptr = bind->getColor();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::BOOL, argv[0]), (JS_ThrowTypeError(ctx, "boolean expected for argument 0 of Color.to_html")));
#endif
			const bool &arg0 = QuickJSBinder::js_to_bool(ctx, argv[0]);

			String ret = ptr->to_html(arg0);
			return QuickJSBinder::to_js_string(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::COLOR,
		"to_rgba32",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Color *ptr = bind->getColor();
			real_t ret = ptr->to_rgba32();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::COLOR,
		"to_rgba64",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Color *ptr = bind->getColor();
			real_t ret = ptr->to_rgba64();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
}

static JSValue Vector3_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) {
	Vector3 tmp;
	
	if (argc == 1) {
		if (ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0])) {
			if (bind->type == Variant::VECTOR3)
				tmp = *bind->getVector3();
		} else {
			tmp.x = QuickJSBinder::js_to_number(ctx, argv[0]);
			tmp.z = tmp.y = tmp.x;
		}
	} else if (argc == 3) {
		tmp.x = QuickJSBinder::js_to_number(ctx, argv[0]);
		tmp.y = QuickJSBinder::js_to_number(ctx, argv[1]);
		tmp.z = QuickJSBinder::js_to_number(ctx, argv[2]);
	}

	JSValue proto = JS_GetProperty(ctx, new_target, QuickJSBinder::JS_ATOM_prototype);
	JSValue obj = JS_NewObjectProtoClass(ctx, proto, QuickJSBinder::get_context_binder(ctx)->get_origin_class_id());
	QuickJSBuiltinBinder::bind_builtin_object(ctx, obj, Variant::VECTOR3, &tmp);
	JS_FreeValue(ctx, proto);
	return obj;
	// return QuickJSBuiltinBinder::create_builtin_value(ctx, Variant::VECTOR3, &tmp);
}

static void bind_Vector3_properties(JSContext *ctx) {
	QuickJSBinder *binder = QuickJSBinder::get_context_binder(ctx);

	JSCFunctionMagic *getter = [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) -> JSValue {
		ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
		const Vector3 *ptr = bind->getVector3();
		switch (magic) {
			case 0:
				return QuickJSBinder::to_js_number(ctx, ptr->x);
			case 1:
				return QuickJSBinder::to_js_number(ctx, ptr->y);
			case 2:
				return QuickJSBinder::to_js_number(ctx, ptr->z);
		}
		return JS_UNDEFINED;
	};
	
	JSCFunctionMagic *setter = [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) -> JSValue {
		ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
		Vector3 *ptr = bind->getVector3();
		switch (magic) {
			case 0:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for Vector3.x")));
#endif
				ptr->x = QuickJSBinder::js_to_number(ctx, argv[0]);
				break;
			case 1:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for Vector3.y")));
#endif
				ptr->y = QuickJSBinder::js_to_number(ctx, argv[0]);
				break;
			case 2:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for Vector3.z")));
#endif
				ptr->z = QuickJSBinder::js_to_number(ctx, argv[0]);
				break;
		}
		return JS_DupValue(ctx, argv[0]);
	};
	binder->get_builtin_binder().register_property(Variant::VECTOR3, "x", getter, setter, 0);
	binder->get_builtin_binder().register_property(Variant::VECTOR3, "y", getter, setter, 1);
	binder->get_builtin_binder().register_property(Variant::VECTOR3, "z", getter, setter, 2);

		
	Vector<JSValue> operators;
	JSValue base_operators = JS_NewObject(ctx);

	JS_SetPropertyStr(ctx, base_operators, "neg",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Vector3 *ptr = bind->getVector3();
			Vector3 ret = ptr->operator-();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"negate",
		1)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "==",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[1]), (JS_ThrowTypeError(ctx, "Vector3 expected for Vector3.operator==")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Vector3 *target = bind1->getVector3();
			bool ret = ptr->operator==(*target);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		"equals",
		2)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "<",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[1]), (JS_ThrowTypeError(ctx, "Vector3 expected for Vector3.operator<")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Vector3 *target = bind1->getVector3();
			bool ret = ptr->operator<(*target);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		"less",
		2)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "+",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[1]), (JS_ThrowTypeError(ctx, "Vector3 expected for Vector3.operator+")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Vector3 *target = bind1->getVector3();
			Vector3 ret = ptr->operator+(*target);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"add",
		2)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "-",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[1]), (JS_ThrowTypeError(ctx, "Vector3 expected for Vector3.operator-")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Vector3 *target = bind1->getVector3();
			Vector3 ret = ptr->operator-(*target);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"subtract",
		2)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "*",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[1]), (JS_ThrowTypeError(ctx, "Vector3 expected for Vector3.operator*")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Vector3 *target = bind1->getVector3();
			Vector3 ret = ptr->operator*(*target);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"multiply",
		2)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "/",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[1]), (JS_ThrowTypeError(ctx, "Vector3 expected for Vector3.operator/")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Vector3 *target = bind1->getVector3();
			Vector3 ret = ptr->operator/(*target);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"multiply",
		2)
	);
	
	operators.push_back(base_operators);
	binder->get_builtin_binder().get_cross_type_operators(Variant::VECTOR3, operators);
	binder->get_builtin_binder().register_operators(Variant::VECTOR3, operators);

	binder->get_builtin_binder().register_constant(Variant::VECTOR3, "AXIS_X", 0);
	binder->get_builtin_binder().register_constant(Variant::VECTOR3, "AXIS_Y", 1);
	binder->get_builtin_binder().register_constant(Variant::VECTOR3, "AXIS_Z", 2);
	binder->get_builtin_binder().register_constant(Variant::VECTOR3, "ZERO", Vector3( 0, 0, 0 ));
	binder->get_builtin_binder().register_constant(Variant::VECTOR3, "ONE", Vector3( 1, 1, 1 ));
	binder->get_builtin_binder().register_constant(Variant::VECTOR3, "INF", Vector3( inf, inf, inf ));
	binder->get_builtin_binder().register_constant(Variant::VECTOR3, "LEFT", Vector3( -1, 0, 0 ));
	binder->get_builtin_binder().register_constant(Variant::VECTOR3, "RIGHT", Vector3( 1, 0, 0 ));
	binder->get_builtin_binder().register_constant(Variant::VECTOR3, "UP", Vector3( 0, 1, 0 ));
	binder->get_builtin_binder().register_constant(Variant::VECTOR3, "DOWN", Vector3( 0, -1, 0 ));
	binder->get_builtin_binder().register_constant(Variant::VECTOR3, "FORWARD", Vector3( 0, 0, -1 ));
	binder->get_builtin_binder().register_constant(Variant::VECTOR3, "BACK", Vector3( 0, 0, 1 ));


	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"abs",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
			Vector3 ret = ptr->abs();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"angle_to",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Vector3.angle_to")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			real_t ret = ptr->angle_to(arg0);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"bounce",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Vector3.bounce")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			Vector3 ret = ptr->bounce(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"ceil",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
			Vector3 ret = ptr->ceil();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"cross",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Vector3.cross")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			Vector3 ret = ptr->cross(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"cubic_interpolate",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Vector3.cubic_interpolate")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[1]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 1 of Vector3.cubic_interpolate")));
#endif
			const Vector3 &arg1 = *(BINDING_DATA_FROM_JS(ctx, argv[1]))->getVector3();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[2]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 2 of Vector3.cubic_interpolate")));
#endif
			const Vector3 &arg2 = *(BINDING_DATA_FROM_JS(ctx, argv[2]))->getVector3();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[3]), (JS_ThrowTypeError(ctx, "number expected for argument 3 of Vector3.cubic_interpolate")));
#endif
			const real_t &arg3 = QuickJSBinder::js_to_number(ctx, argv[3]);

			Vector3 ret = ptr->cubic_interpolate(arg0, arg1, arg2, arg3);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		4);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"direction_to",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Vector3.direction_to")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			Vector3 ret = ptr->direction_to(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"distance_squared_to",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Vector3.distance_squared_to")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			real_t ret = ptr->distance_squared_to(arg0);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"distance_to",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Vector3.distance_to")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			real_t ret = ptr->distance_to(arg0);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"dot",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Vector3.dot")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			real_t ret = ptr->dot(arg0);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"floor",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
			Vector3 ret = ptr->floor();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"inverse",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
			Vector3 ret = ptr->inverse();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"is_equal_approx",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Vector3.is_equal_approx")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			bool ret = ptr->is_equal_approx(arg0);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"is_normalized",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
			bool ret = ptr->is_normalized();
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"length",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
			real_t ret = ptr->length();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"length_squared",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
			real_t ret = ptr->length_squared();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"linear_interpolate",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Vector3.linear_interpolate")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of Vector3.linear_interpolate")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			Vector3 ret = ptr->linear_interpolate(arg0, arg1);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"max_axis",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
			real_t ret = ptr->max_axis();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"min_axis",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
			real_t ret = ptr->min_axis();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"move_toward",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Vector3.move_toward")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of Vector3.move_toward")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			Vector3 ret = ptr->move_toward(arg0, arg1);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"normalized",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
			Vector3 ret = ptr->normalized();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"outer",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Vector3.outer")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			Basis ret = ptr->outer(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"posmod",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of Vector3.posmod")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			Vector3 ret = ptr->posmod(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"posmodv",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Vector3.posmodv")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			Vector3 ret = ptr->posmodv(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"project",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Vector3.project")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			Vector3 ret = ptr->project(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"reflect",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Vector3.reflect")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			Vector3 ret = ptr->reflect(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"rotated",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Vector3.rotated")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of Vector3.rotated")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			Vector3 ret = ptr->rotated(arg0, arg1);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"round",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
			Vector3 ret = ptr->round();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"sign",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
			Vector3 ret = ptr->sign();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"signed_angle_to",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Vector3.signed_angle_to")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[1]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 1 of Vector3.signed_angle_to")));
#endif
			const Vector3 &arg1 = *(BINDING_DATA_FROM_JS(ctx, argv[1]))->getVector3();

			real_t ret = ptr->signed_angle_to(arg0, arg1);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"slerp",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Vector3.slerp")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of Vector3.slerp")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			Vector3 ret = ptr->slerp(arg0, arg1);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"slide",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Vector3.slide")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			Vector3 ret = ptr->slide(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"snapped",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Vector3.snapped")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			Vector3 ret = ptr->snapped(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::VECTOR3,
		"to_diagonal_matrix",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Vector3 *ptr = bind->getVector3();
			Basis ret = ptr->to_diagonal_matrix();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
}

static JSValue Basis_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) {
	Basis tmp;
	
	if (argc == 3) {
#ifdef DEBUG_METHODS_ENABLED
		ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Basis(x_axis, y_axis, z_axis)")));
		ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[1]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 1 of Basis(x_axis, y_axis, z_axis)")));
		ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[2]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 2 of Basis(x_axis, y_axis, z_axis)")));
#endif
		ECMAScriptGCHandler *param0 = BINDING_DATA_FROM_JS(ctx, argv[0]);
		ECMAScriptGCHandler *param1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
		ECMAScriptGCHandler *param2 = BINDING_DATA_FROM_JS(ctx, argv[2]);
		tmp.elements[0].operator=(*param0->getVector3());
		tmp.elements[1].operator=(*param1->getVector3());
		tmp.elements[2].operator=(*param2->getVector3());
	} else if (argc == 2) {
#ifdef DEBUG_METHODS_ENABLED
		ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Basis(axis, phi)")));
#endif
		ECMAScriptGCHandler *param0 = BINDING_DATA_FROM_JS(ctx, argv[0]);
		tmp.set_axis_angle(*param0->getVector3(), QuickJSBinder::js_to_number(ctx, argv[1]));
	} else if (argc == 1) {
		if (ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0])) {
			if (bind->type == Variant::VECTOR3) {
				tmp.set_euler(*bind->getVector3());
			} else if (bind->type == Variant::QUAT) {
				tmp.set_quat(*bind->getQuat());
			} else if (bind->type == Variant::BASIS) {
				tmp.operator=(*bind->getBasis());
			}
		}
	}

	JSValue proto = JS_GetProperty(ctx, new_target, QuickJSBinder::JS_ATOM_prototype);
	JSValue obj = JS_NewObjectProtoClass(ctx, proto, QuickJSBinder::get_context_binder(ctx)->get_origin_class_id());
	QuickJSBuiltinBinder::bind_builtin_object(ctx, obj, Variant::BASIS, &tmp);
	JS_FreeValue(ctx, proto);
	return obj;
	// return QuickJSBuiltinBinder::create_builtin_value(ctx, Variant::BASIS, &tmp);
}

static void bind_Basis_properties(JSContext *ctx) {
	QuickJSBinder *binder = QuickJSBinder::get_context_binder(ctx);

	JSCFunctionMagic *getter = [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) -> JSValue {
		ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
		const Basis *ptr = bind->getBasis();
		switch (magic) {
			case 0:
				return QuickJSBuiltinBinder::new_object_from(ctx, ptr->elements[0]);
			case 1:
				return QuickJSBuiltinBinder::new_object_from(ctx, ptr->elements[1]);
			case 2:
				return QuickJSBuiltinBinder::new_object_from(ctx, ptr->elements[2]);
		}
		return JS_UNDEFINED;
	};
	
	JSCFunctionMagic *setter = [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) -> JSValue {
		ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
		Basis *ptr = bind->getBasis();
		switch (magic) {
			case 0:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for Basis.x")));
#endif
				ptr->elements[0] = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();
				break;
			case 1:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for Basis.y")));
#endif
				ptr->elements[1] = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();
				break;
			case 2:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for Basis.z")));
#endif
				ptr->elements[2] = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();
				break;
		}
		return JS_DupValue(ctx, argv[0]);
	};
	binder->get_builtin_binder().register_property(Variant::BASIS, "x", getter, setter, 0);
	binder->get_builtin_binder().register_property(Variant::BASIS, "y", getter, setter, 1);
	binder->get_builtin_binder().register_property(Variant::BASIS, "z", getter, setter, 2);

		
	Vector<JSValue> operators;
	JSValue base_operators = JS_NewObject(ctx);

	JS_SetPropertyStr(ctx, base_operators, "==",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Basis *ptr = bind->getBasis();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::BASIS, argv[1]), (JS_ThrowTypeError(ctx, "Basis expected for Basis.operator==")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Basis *target = bind1->getBasis();
			bool ret = ptr->operator==(*target);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		"equals",
		2)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "+",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Basis *ptr = bind->getBasis();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::BASIS, argv[1]), (JS_ThrowTypeError(ctx, "Basis expected for Basis.operator+")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Basis *target = bind1->getBasis();
			Basis ret = ptr->operator+(*target);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"add",
		2)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "-",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Basis *ptr = bind->getBasis();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::BASIS, argv[1]), (JS_ThrowTypeError(ctx, "Basis expected for Basis.operator-")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Basis *target = bind1->getBasis();
			Basis ret = ptr->operator-(*target);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"subtract",
		2)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "*",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Basis *ptr = bind->getBasis();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::BASIS, argv[1]), (JS_ThrowTypeError(ctx, "Basis expected for Basis.operator*")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Basis *target = bind1->getBasis();
			Basis ret = ptr->operator*(*target);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"multiply",
		2)
	);
	
	operators.push_back(base_operators);
	binder->get_builtin_binder().get_cross_type_operators(Variant::BASIS, operators);
	binder->get_builtin_binder().register_operators(Variant::BASIS, operators);

	binder->get_builtin_binder().register_constant(Variant::BASIS, "IDENTITY", Basis( 1, 0, 0, 0, 1, 0, 0, 0, 1 ));
	binder->get_builtin_binder().register_constant(Variant::BASIS, "FLIP_X", Basis( -1, 0, 0, 0, 1, 0, 0, 0, 1 ));
	binder->get_builtin_binder().register_constant(Variant::BASIS, "FLIP_Y", Basis( 1, 0, 0, 0, -1, 0, 0, 0, 1 ));
	binder->get_builtin_binder().register_constant(Variant::BASIS, "FLIP_Z", Basis( 1, 0, 0, 0, 1, 0, 0, 0, -1 ));


	binder->get_builtin_binder().register_method(
		Variant::BASIS,
		"determinant",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Basis *ptr = bind->getBasis();
			real_t ret = ptr->determinant();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::BASIS,
		"get_euler",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Basis *ptr = bind->getBasis();
			Vector3 ret = ptr->get_euler();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::BASIS,
		"get_orthogonal_index",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Basis *ptr = bind->getBasis();
			real_t ret = ptr->get_orthogonal_index();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::BASIS,
		"get_rotation_quat",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Basis *ptr = bind->getBasis();
			Quat ret = ptr->get_rotation_quat();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::BASIS,
		"get_scale",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Basis *ptr = bind->getBasis();
			Vector3 ret = ptr->get_scale();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::BASIS,
		"inverse",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Basis *ptr = bind->getBasis();
			Basis ret = ptr->inverse();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::BASIS,
		"orthonormalized",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Basis *ptr = bind->getBasis();
			Basis ret = ptr->orthonormalized();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::BASIS,
		"rotated",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Basis *ptr = bind->getBasis();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Basis.rotated")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of Basis.rotated")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			Basis ret = ptr->rotated(arg0, arg1);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::BASIS,
		"scaled",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Basis *ptr = bind->getBasis();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Basis.scaled")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			Basis ret = ptr->scaled(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::BASIS,
		"slerp",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Basis *ptr = bind->getBasis();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::BASIS, argv[0]), (JS_ThrowTypeError(ctx, "Basis expected for argument 0 of Basis.slerp")));
#endif
			const Basis &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getBasis();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of Basis.slerp")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			Basis ret = ptr->slerp(arg0, arg1);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::BASIS,
		"tdotx",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Basis *ptr = bind->getBasis();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Basis.tdotx")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			real_t ret = ptr->tdotx(arg0);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::BASIS,
		"tdoty",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Basis *ptr = bind->getBasis();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Basis.tdoty")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			real_t ret = ptr->tdoty(arg0);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::BASIS,
		"tdotz",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Basis *ptr = bind->getBasis();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Basis.tdotz")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			real_t ret = ptr->tdotz(arg0);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::BASIS,
		"transposed",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Basis *ptr = bind->getBasis();
			Basis ret = ptr->transposed();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::BASIS,
		"xform",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Basis *ptr = bind->getBasis();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Basis.xform")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			Vector3 ret = ptr->xform(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::BASIS,
		"xform_inv",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Basis *ptr = bind->getBasis();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Basis.xform_inv")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			Vector3 ret = ptr->xform_inv(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
}

static JSValue Quat_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) {
	Quat tmp;
	
	if (argc == 4) {
		tmp.x = QuickJSBinder::js_to_number(ctx, argv[0]);
		tmp.y = QuickJSBinder::js_to_number(ctx, argv[1]);
		tmp.z = QuickJSBinder::js_to_number(ctx, argv[2]);
		tmp.w = QuickJSBinder::js_to_number(ctx, argv[3]);
	} else if (argc == 2) {
#ifdef DEBUG_METHODS_ENABLED
		ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Quat(axis, angle)")));
#endif
		ECMAScriptGCHandler *param0 = BINDING_DATA_FROM_JS(ctx, argv[0]);
		tmp = Quat(*param0->getVector3(), QuickJSBinder::js_to_number(ctx, argv[1]));
	} else if (argc == 1) {
		if (ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0])) {
			if (bind->type == Variant::QUAT) {
				tmp = *bind->getQuat();
			} else if (bind->type == Variant::BASIS) {
				tmp = *bind->getBasis();
			} else if (bind->type == Variant::VECTOR3) {
				tmp.set_euler(*bind->getVector3());
			}
		}
	}

	JSValue proto = JS_GetProperty(ctx, new_target, QuickJSBinder::JS_ATOM_prototype);
	JSValue obj = JS_NewObjectProtoClass(ctx, proto, QuickJSBinder::get_context_binder(ctx)->get_origin_class_id());
	QuickJSBuiltinBinder::bind_builtin_object(ctx, obj, Variant::QUAT, &tmp);
	JS_FreeValue(ctx, proto);
	return obj;
	// return QuickJSBuiltinBinder::create_builtin_value(ctx, Variant::QUAT, &tmp);
}

static void bind_Quat_properties(JSContext *ctx) {
	QuickJSBinder *binder = QuickJSBinder::get_context_binder(ctx);

	JSCFunctionMagic *getter = [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) -> JSValue {
		ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
		const Quat *ptr = bind->getQuat();
		switch (magic) {
			case 0:
				return QuickJSBinder::to_js_number(ctx, ptr->w);
			case 1:
				return QuickJSBinder::to_js_number(ctx, ptr->x);
			case 2:
				return QuickJSBinder::to_js_number(ctx, ptr->y);
			case 3:
				return QuickJSBinder::to_js_number(ctx, ptr->z);
		}
		return JS_UNDEFINED;
	};
	
	JSCFunctionMagic *setter = [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) -> JSValue {
		ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
		Quat *ptr = bind->getQuat();
		switch (magic) {
			case 0:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for Quat.w")));
#endif
				ptr->w = QuickJSBinder::js_to_number(ctx, argv[0]);
				break;
			case 1:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for Quat.x")));
#endif
				ptr->x = QuickJSBinder::js_to_number(ctx, argv[0]);
				break;
			case 2:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for Quat.y")));
#endif
				ptr->y = QuickJSBinder::js_to_number(ctx, argv[0]);
				break;
			case 3:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for Quat.z")));
#endif
				ptr->z = QuickJSBinder::js_to_number(ctx, argv[0]);
				break;
		}
		return JS_DupValue(ctx, argv[0]);
	};
	binder->get_builtin_binder().register_property(Variant::QUAT, "w", getter, setter, 0);
	binder->get_builtin_binder().register_property(Variant::QUAT, "x", getter, setter, 1);
	binder->get_builtin_binder().register_property(Variant::QUAT, "y", getter, setter, 2);
	binder->get_builtin_binder().register_property(Variant::QUAT, "z", getter, setter, 3);

		
	Vector<JSValue> operators;
	JSValue base_operators = JS_NewObject(ctx);

	JS_SetPropertyStr(ctx, base_operators, "neg",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Quat *ptr = bind->getQuat();
			Quat ret = ptr->operator-();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"negate",
		1)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "==",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Quat *ptr = bind->getQuat();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::QUAT, argv[1]), (JS_ThrowTypeError(ctx, "Quat expected for Quat.operator==")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Quat *target = bind1->getQuat();
			bool ret = ptr->operator==(*target);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		"equals",
		2)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "+",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Quat *ptr = bind->getQuat();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::QUAT, argv[1]), (JS_ThrowTypeError(ctx, "Quat expected for Quat.operator+")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Quat *target = bind1->getQuat();
			Quat ret = ptr->operator+(*target);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"add",
		2)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "-",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Quat *ptr = bind->getQuat();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::QUAT, argv[1]), (JS_ThrowTypeError(ctx, "Quat expected for Quat.operator-")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Quat *target = bind1->getQuat();
			Quat ret = ptr->operator-(*target);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"subtract",
		2)
	);
	
	operators.push_back(base_operators);
	binder->get_builtin_binder().get_cross_type_operators(Variant::QUAT, operators);
	binder->get_builtin_binder().register_operators(Variant::QUAT, operators);

	binder->get_builtin_binder().register_constant(Variant::QUAT, "IDENTITY", Quat( 0, 0, 0, 1 ));


	binder->get_builtin_binder().register_method(
		Variant::QUAT,
		"angle_to",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Quat *ptr = bind->getQuat();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::QUAT, argv[0]), (JS_ThrowTypeError(ctx, "Quat expected for argument 0 of Quat.angle_to")));
#endif
			const Quat &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getQuat();

			real_t ret = ptr->angle_to(arg0);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::QUAT,
		"cubic_slerp",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Quat *ptr = bind->getQuat();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::QUAT, argv[0]), (JS_ThrowTypeError(ctx, "Quat expected for argument 0 of Quat.cubic_slerp")));
#endif
			const Quat &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getQuat();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::QUAT, argv[1]), (JS_ThrowTypeError(ctx, "Quat expected for argument 1 of Quat.cubic_slerp")));
#endif
			const Quat &arg1 = *(BINDING_DATA_FROM_JS(ctx, argv[1]))->getQuat();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::QUAT, argv[2]), (JS_ThrowTypeError(ctx, "Quat expected for argument 2 of Quat.cubic_slerp")));
#endif
			const Quat &arg2 = *(BINDING_DATA_FROM_JS(ctx, argv[2]))->getQuat();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[3]), (JS_ThrowTypeError(ctx, "number expected for argument 3 of Quat.cubic_slerp")));
#endif
			const real_t &arg3 = QuickJSBinder::js_to_number(ctx, argv[3]);

			Quat ret = ptr->cubic_slerp(arg0, arg1, arg2, arg3);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		4);
	binder->get_builtin_binder().register_method(
		Variant::QUAT,
		"dot",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Quat *ptr = bind->getQuat();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::QUAT, argv[0]), (JS_ThrowTypeError(ctx, "Quat expected for argument 0 of Quat.dot")));
#endif
			const Quat &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getQuat();

			real_t ret = ptr->dot(arg0);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::QUAT,
		"get_euler",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Quat *ptr = bind->getQuat();
			Vector3 ret = ptr->get_euler();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::QUAT,
		"inverse",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Quat *ptr = bind->getQuat();
			Quat ret = ptr->inverse();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::QUAT,
		"is_equal_approx",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Quat *ptr = bind->getQuat();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::QUAT, argv[0]), (JS_ThrowTypeError(ctx, "Quat expected for argument 0 of Quat.is_equal_approx")));
#endif
			const Quat &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getQuat();

			bool ret = ptr->is_equal_approx(arg0);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::QUAT,
		"is_normalized",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Quat *ptr = bind->getQuat();
			bool ret = ptr->is_normalized();
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::QUAT,
		"length",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Quat *ptr = bind->getQuat();
			real_t ret = ptr->length();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::QUAT,
		"length_squared",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Quat *ptr = bind->getQuat();
			real_t ret = ptr->length_squared();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::QUAT,
		"normalized",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Quat *ptr = bind->getQuat();
			Quat ret = ptr->normalized();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::QUAT,
		"set_axis_angle",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Quat *ptr = bind->getQuat();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Quat.set_axis_angle")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of Quat.set_axis_angle")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			ptr->set_axis_angle(arg0, arg1);
			return JS_UNDEFINED;
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::QUAT,
		"set_euler",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Quat *ptr = bind->getQuat();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Quat.set_euler")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			ptr->set_euler(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::QUAT,
		"slerp",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Quat *ptr = bind->getQuat();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::QUAT, argv[0]), (JS_ThrowTypeError(ctx, "Quat expected for argument 0 of Quat.slerp")));
#endif
			const Quat &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getQuat();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of Quat.slerp")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			Quat ret = ptr->slerp(arg0, arg1);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::QUAT,
		"slerpni",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Quat *ptr = bind->getQuat();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::QUAT, argv[0]), (JS_ThrowTypeError(ctx, "Quat expected for argument 0 of Quat.slerpni")));
#endif
			const Quat &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getQuat();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of Quat.slerpni")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			Quat ret = ptr->slerpni(arg0, arg1);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::QUAT,
		"xform",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Quat *ptr = bind->getQuat();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Quat.xform")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			Vector3 ret = ptr->xform(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
}

static JSValue RID_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) {
	RID tmp;
	
	JSValue proto = JS_GetProperty(ctx, new_target, QuickJSBinder::JS_ATOM_prototype);
	JSValue obj = JS_NewObjectProtoClass(ctx, proto, QuickJSBinder::get_context_binder(ctx)->get_origin_class_id());
	QuickJSBuiltinBinder::bind_builtin_object(ctx, obj, Variant::_RID, &tmp);
	JS_FreeValue(ctx, proto);
	return obj;
	// return QuickJSBuiltinBinder::create_builtin_value(ctx, Variant::_RID, &tmp);
}

static void bind_RID_properties(JSContext *ctx) {
	QuickJSBinder *binder = QuickJSBinder::get_context_binder(ctx);

	Vector<JSValue> operators;
	JSValue base_operators = JS_NewObject(ctx);

	JS_SetPropertyStr(ctx, base_operators, "==",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			RID *ptr = bind->getRID();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::_RID, argv[1]), (JS_ThrowTypeError(ctx, "RID expected for RID.operator==")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			RID *target = bind1->getRID();
			bool ret = ptr->operator==(*target);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		"equals",
		2)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "<",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			RID *ptr = bind->getRID();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::_RID, argv[1]), (JS_ThrowTypeError(ctx, "RID expected for RID.operator<")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			RID *target = bind1->getRID();
			bool ret = ptr->operator<(*target);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		"less",
		2)
	);
	
	operators.push_back(base_operators);
	binder->get_builtin_binder().get_cross_type_operators(Variant::_RID, operators);
	binder->get_builtin_binder().register_operators(Variant::_RID, operators);



	binder->get_builtin_binder().register_method(
		Variant::_RID,
		"get_id",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			RID *ptr = bind->getRID();
			real_t ret = ptr->get_id();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
}

static JSValue Transform2D_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) {
	Transform2D tmp;
	
	if (argc == 3) {
#ifdef DEBUG_METHODS_ENABLED
		ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Transform2D(x_axis, y_axis, origin)")));
		ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[1]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 1 of Transform2D(x_axis, y_axis, origin)")));
		ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[2]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 2 of Transform2D(x_axis, y_axis, origin)")));
#endif
		ECMAScriptGCHandler *param0 = BINDING_DATA_FROM_JS(ctx, argv[0]);
		ECMAScriptGCHandler *param1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
		ECMAScriptGCHandler *param2 = BINDING_DATA_FROM_JS(ctx, argv[2]);
		tmp.elements[0].operator=(*param0->getVector2());
		tmp.elements[1].operator=(*param1->getVector2());
		tmp.elements[2].operator=(*param2->getVector2());
	} else if (argc == 2) {
#ifdef DEBUG_METHODS_ENABLED
		ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[1]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 1 of Transform2D(rotation, position)")));
#endif
		ECMAScriptGCHandler *param1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
		tmp.set_origin(*param1->getVector2());
		tmp.set_rotation(QuickJSBinder::js_to_number(ctx, argv[0]));
	} else if (argc == 1) {
		if (ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0])) {
			if (bind->type == Variant::TRANSFORM2D)
				tmp = *bind->getTransform2D();
			else if (Variant::can_convert(bind->type, Variant::TRANSFORM2D)) {
				tmp = bind->get_value();
			}
		}
	}

	JSValue proto = JS_GetProperty(ctx, new_target, QuickJSBinder::JS_ATOM_prototype);
	JSValue obj = JS_NewObjectProtoClass(ctx, proto, QuickJSBinder::get_context_binder(ctx)->get_origin_class_id());
	QuickJSBuiltinBinder::bind_builtin_object(ctx, obj, Variant::TRANSFORM2D, &tmp);
	JS_FreeValue(ctx, proto);
	return obj;
	// return QuickJSBuiltinBinder::create_builtin_value(ctx, Variant::TRANSFORM2D, &tmp);
}

static void bind_Transform2D_properties(JSContext *ctx) {
	QuickJSBinder *binder = QuickJSBinder::get_context_binder(ctx);

	JSCFunctionMagic *getter = [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) -> JSValue {
		ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
		const Transform2D *ptr = bind->getTransform2D();
		switch (magic) {
			case 0:
				return QuickJSBuiltinBinder::new_object_from(ctx, ptr->elements[2]);
			case 1:
				return QuickJSBuiltinBinder::new_object_from(ctx, ptr->elements[0]);
			case 2:
				return QuickJSBuiltinBinder::new_object_from(ctx, ptr->elements[1]);
		}
		return JS_UNDEFINED;
	};
	
	JSCFunctionMagic *setter = [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) -> JSValue {
		ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
		Transform2D *ptr = bind->getTransform2D();
		switch (magic) {
			case 0:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for Transform2D.origin")));
#endif
				ptr->elements[2] = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();
				break;
			case 1:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for Transform2D.x")));
#endif
				ptr->elements[0] = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();
				break;
			case 2:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for Transform2D.y")));
#endif
				ptr->elements[1] = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();
				break;
		}
		return JS_DupValue(ctx, argv[0]);
	};
	binder->get_builtin_binder().register_property(Variant::TRANSFORM2D, "origin", getter, setter, 0);
	binder->get_builtin_binder().register_property(Variant::TRANSFORM2D, "x", getter, setter, 1);
	binder->get_builtin_binder().register_property(Variant::TRANSFORM2D, "y", getter, setter, 2);

		
	Vector<JSValue> operators;
	JSValue base_operators = JS_NewObject(ctx);

	JS_SetPropertyStr(ctx, base_operators, "==",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Transform2D *ptr = bind->getTransform2D();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::TRANSFORM2D, argv[1]), (JS_ThrowTypeError(ctx, "Transform2D expected for Transform2D.operator==")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Transform2D *target = bind1->getTransform2D();
			bool ret = ptr->operator==(*target);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		"equals",
		2)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "*",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Transform2D *ptr = bind->getTransform2D();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::TRANSFORM2D, argv[1]), (JS_ThrowTypeError(ctx, "Transform2D expected for Transform2D.operator*")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Transform2D *target = bind1->getTransform2D();
			Transform2D ret = ptr->operator*(*target);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"multiply",
		2)
	);
	
	operators.push_back(base_operators);
	binder->get_builtin_binder().get_cross_type_operators(Variant::TRANSFORM2D, operators);
	binder->get_builtin_binder().register_operators(Variant::TRANSFORM2D, operators);

	binder->get_builtin_binder().register_constant(Variant::TRANSFORM2D, "IDENTITY", Transform2D( 1, 0, 0, 1, 0, 0 ));
	binder->get_builtin_binder().register_constant(Variant::TRANSFORM2D, "FLIP_X", Transform2D( -1, 0, 0, 1, 0, 0 ));
	binder->get_builtin_binder().register_constant(Variant::TRANSFORM2D, "FLIP_Y", Transform2D( 1, 0, 0, -1, 0, 0 ));


	binder->get_builtin_binder().register_method(
		Variant::TRANSFORM2D,
		"affine_inverse",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Transform2D *ptr = bind->getTransform2D();
			Transform2D ret = ptr->affine_inverse();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::TRANSFORM2D,
		"basis_xform",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Transform2D *ptr = bind->getTransform2D();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Transform2D.basis_xform")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

			Vector2 ret = ptr->basis_xform(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::TRANSFORM2D,
		"basis_xform_inv",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Transform2D *ptr = bind->getTransform2D();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Transform2D.basis_xform_inv")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

			Vector2 ret = ptr->basis_xform_inv(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::TRANSFORM2D,
		"get_origin",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Transform2D *ptr = bind->getTransform2D();
			Vector2 ret = ptr->get_origin();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::TRANSFORM2D,
		"get_rotation",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Transform2D *ptr = bind->getTransform2D();
			real_t ret = ptr->get_rotation();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::TRANSFORM2D,
		"get_scale",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Transform2D *ptr = bind->getTransform2D();
			Vector2 ret = ptr->get_scale();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::TRANSFORM2D,
		"interpolate_with",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Transform2D *ptr = bind->getTransform2D();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::TRANSFORM2D, argv[0]), (JS_ThrowTypeError(ctx, "Transform2D expected for argument 0 of Transform2D.interpolate_with")));
#endif
			const Transform2D &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getTransform2D();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of Transform2D.interpolate_with")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			Transform2D ret = ptr->interpolate_with(arg0, arg1);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::TRANSFORM2D,
		"inverse",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Transform2D *ptr = bind->getTransform2D();
			Transform2D ret = ptr->inverse();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::TRANSFORM2D,
		"is_equal_approx",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Transform2D *ptr = bind->getTransform2D();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::TRANSFORM2D, argv[0]), (JS_ThrowTypeError(ctx, "Transform2D expected for argument 0 of Transform2D.is_equal_approx")));
#endif
			const Transform2D &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getTransform2D();

			bool ret = ptr->is_equal_approx(arg0);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::TRANSFORM2D,
		"orthonormalized",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Transform2D *ptr = bind->getTransform2D();
			Transform2D ret = ptr->orthonormalized();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::TRANSFORM2D,
		"rotated",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Transform2D *ptr = bind->getTransform2D();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of Transform2D.rotated")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			Transform2D ret = ptr->rotated(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::TRANSFORM2D,
		"scaled",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Transform2D *ptr = bind->getTransform2D();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Transform2D.scaled")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

			Transform2D ret = ptr->scaled(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::TRANSFORM2D,
		"translated",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Transform2D *ptr = bind->getTransform2D();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of Transform2D.translated")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

			Transform2D ret = ptr->translated(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
}

static JSValue Plane_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) {
	Plane tmp;
	
	if (argc == 4) {
		tmp.normal.x = QuickJSBinder::js_to_number(ctx, argv[0]);
		tmp.normal.y = QuickJSBinder::js_to_number(ctx, argv[1]);
		tmp.normal.z = QuickJSBinder::js_to_number(ctx, argv[2]);
		tmp.d = QuickJSBinder::js_to_number(ctx, argv[3]);
	} else if (argc == 3) {
#ifdef DEBUG_METHODS_ENABLED
		ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Plane(v1, v2, v3)")));
		ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[1]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 1 of Plane(v1, v2, v3)")));
		ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[2]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 2 of Plane(v1, v2, v3)")));
#endif
		ECMAScriptGCHandler *param0 = BINDING_DATA_FROM_JS(ctx, argv[0]);
		ECMAScriptGCHandler *param1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
		ECMAScriptGCHandler *param2 = BINDING_DATA_FROM_JS(ctx, argv[2]);
		tmp = Plane(*param0->getVector3(), *param1->getVector3(), *param2->getVector3());
	} else if (argc == 2) {
#ifdef DEBUG_METHODS_ENABLED
		ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Plane(normal, d)")));
#endif
		ECMAScriptGCHandler *param0 = BINDING_DATA_FROM_JS(ctx, argv[0]);
		tmp = Plane(*param0->getVector3(), QuickJSBinder::js_to_number(ctx, argv[1]));
	} else if (argc == 1) {
		if (ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0])) {
			if (bind->type == Variant::PLANE)
				tmp = *bind->getPlane();
		}
	}

	JSValue proto = JS_GetProperty(ctx, new_target, QuickJSBinder::JS_ATOM_prototype);
	JSValue obj = JS_NewObjectProtoClass(ctx, proto, QuickJSBinder::get_context_binder(ctx)->get_origin_class_id());
	QuickJSBuiltinBinder::bind_builtin_object(ctx, obj, Variant::PLANE, &tmp);
	JS_FreeValue(ctx, proto);
	return obj;
	// return QuickJSBuiltinBinder::create_builtin_value(ctx, Variant::PLANE, &tmp);
}

static void bind_Plane_properties(JSContext *ctx) {
	QuickJSBinder *binder = QuickJSBinder::get_context_binder(ctx);

	JSCFunctionMagic *getter = [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) -> JSValue {
		ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
		const Plane *ptr = bind->getPlane();
		switch (magic) {
			case 0:
				return QuickJSBinder::to_js_number(ctx, ptr->d);
			case 1:
				return QuickJSBuiltinBinder::new_object_from(ctx, ptr->normal);
			case 2:
				return QuickJSBinder::to_js_number(ctx, ptr->normal.x);
			case 3:
				return QuickJSBinder::to_js_number(ctx, ptr->normal.y);
			case 4:
				return QuickJSBinder::to_js_number(ctx, ptr->normal.z);
		}
		return JS_UNDEFINED;
	};
	
	JSCFunctionMagic *setter = [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) -> JSValue {
		ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
		Plane *ptr = bind->getPlane();
		switch (magic) {
			case 0:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for Plane.d")));
#endif
				ptr->d = QuickJSBinder::js_to_number(ctx, argv[0]);
				break;
			case 1:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for Plane.normal")));
#endif
				ptr->normal = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();
				break;
			case 2:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for Plane.x")));
#endif
				ptr->normal.x = QuickJSBinder::js_to_number(ctx, argv[0]);
				break;
			case 3:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for Plane.y")));
#endif
				ptr->normal.y = QuickJSBinder::js_to_number(ctx, argv[0]);
				break;
			case 4:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for Plane.z")));
#endif
				ptr->normal.z = QuickJSBinder::js_to_number(ctx, argv[0]);
				break;
		}
		return JS_DupValue(ctx, argv[0]);
	};
	binder->get_builtin_binder().register_property(Variant::PLANE, "d", getter, setter, 0);
	binder->get_builtin_binder().register_property(Variant::PLANE, "normal", getter, setter, 1);
	binder->get_builtin_binder().register_property(Variant::PLANE, "x", getter, setter, 2);
	binder->get_builtin_binder().register_property(Variant::PLANE, "y", getter, setter, 3);
	binder->get_builtin_binder().register_property(Variant::PLANE, "z", getter, setter, 4);

		
	Vector<JSValue> operators;
	JSValue base_operators = JS_NewObject(ctx);

	JS_SetPropertyStr(ctx, base_operators, "neg",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Plane *ptr = bind->getPlane();
			Plane ret = ptr->operator-();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"negate",
		1)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "==",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Plane *ptr = bind->getPlane();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::PLANE, argv[1]), (JS_ThrowTypeError(ctx, "Plane expected for Plane.operator==")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Plane *target = bind1->getPlane();
			bool ret = ptr->operator==(*target);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		"equals",
		2)
	);
	
	operators.push_back(base_operators);
	binder->get_builtin_binder().get_cross_type_operators(Variant::PLANE, operators);
	binder->get_builtin_binder().register_operators(Variant::PLANE, operators);

	binder->get_builtin_binder().register_constant(Variant::PLANE, "PLANE_YZ", Plane( 1, 0, 0, 0 ));
	binder->get_builtin_binder().register_constant(Variant::PLANE, "PLANE_XZ", Plane( 0, 1, 0, 0 ));
	binder->get_builtin_binder().register_constant(Variant::PLANE, "PLANE_XY", Plane( 0, 0, 1, 0 ));


	binder->get_builtin_binder().register_method(
		Variant::PLANE,
		"center",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Plane *ptr = bind->getPlane();
			Vector3 ret = ptr->center();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::PLANE,
		"distance_to",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Plane *ptr = bind->getPlane();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Plane.distance_to")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			real_t ret = ptr->distance_to(arg0);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::PLANE,
		"get_any_point",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Plane *ptr = bind->getPlane();
			Vector3 ret = ptr->get_any_point();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::PLANE,
		"has_point",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Plane *ptr = bind->getPlane();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Plane.has_point")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of Plane.has_point")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			bool ret = ptr->has_point(arg0, arg1);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::PLANE,
		"is_equal_approx",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Plane *ptr = bind->getPlane();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::PLANE, argv[0]), (JS_ThrowTypeError(ctx, "Plane expected for argument 0 of Plane.is_equal_approx")));
#endif
			const Plane &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getPlane();

			bool ret = ptr->is_equal_approx(arg0);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::PLANE,
		"is_point_over",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Plane *ptr = bind->getPlane();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Plane.is_point_over")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			bool ret = ptr->is_point_over(arg0);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::PLANE,
		"normalized",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Plane *ptr = bind->getPlane();
			Plane ret = ptr->normalized();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::PLANE,
		"project",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Plane *ptr = bind->getPlane();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Plane.project")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			Vector3 ret = ptr->project(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
}

static JSValue AABB_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) {
	AABB tmp;
	
	if (argc == 2) {
#ifdef DEBUG_METHODS_ENABLED
		ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of AABB(position, size)")));
		ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[1]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 1 of AABB(position, size)")));
#endif
		ECMAScriptGCHandler *param0 = BINDING_DATA_FROM_JS(ctx, argv[0]);
		ECMAScriptGCHandler *param1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
		tmp.position = *param0->getVector3();
		tmp.size = *param1->getVector3();
	} else if (argc == 1) {
		if (ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0])) {
			if (bind->type == Variant::AABB)
				tmp = *bind->getAABB();
		}
	}

	JSValue proto = JS_GetProperty(ctx, new_target, QuickJSBinder::JS_ATOM_prototype);
	JSValue obj = JS_NewObjectProtoClass(ctx, proto, QuickJSBinder::get_context_binder(ctx)->get_origin_class_id());
	QuickJSBuiltinBinder::bind_builtin_object(ctx, obj, Variant::AABB, &tmp);
	JS_FreeValue(ctx, proto);
	return obj;
	// return QuickJSBuiltinBinder::create_builtin_value(ctx, Variant::AABB, &tmp);
}

static void bind_AABB_properties(JSContext *ctx) {
	QuickJSBinder *binder = QuickJSBinder::get_context_binder(ctx);

	JSCFunctionMagic *getter = [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) -> JSValue {
		ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
		const AABB *ptr = bind->getAABB();
		switch (magic) {
			case 0:
				return QuickJSBuiltinBinder::new_object_from(ctx, ptr->position);
			case 1:
				return QuickJSBuiltinBinder::new_object_from(ctx, ptr->size);
		}
		return JS_UNDEFINED;
	};
	
	JSCFunctionMagic *setter = [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) -> JSValue {
		ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
		AABB *ptr = bind->getAABB();
		switch (magic) {
			case 0:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for AABB.position")));
#endif
				ptr->position = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();
				break;
			case 1:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for AABB.size")));
#endif
				ptr->size = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();
				break;
		}
		return JS_DupValue(ctx, argv[0]);
	};
	binder->get_builtin_binder().register_property(Variant::AABB, "position", getter, setter, 0);
	binder->get_builtin_binder().register_property(Variant::AABB, "size", getter, setter, 1);

		
	Vector<JSValue> operators;
	JSValue base_operators = JS_NewObject(ctx);

	JS_SetPropertyStr(ctx, base_operators, "==",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			AABB *ptr = bind->getAABB();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::AABB, argv[1]), (JS_ThrowTypeError(ctx, "AABB expected for AABB.operator==")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			AABB *target = bind1->getAABB();
			bool ret = ptr->operator==(*target);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		"equals",
		2)
	);
	
	operators.push_back(base_operators);
	binder->get_builtin_binder().get_cross_type_operators(Variant::AABB, operators);
	binder->get_builtin_binder().register_operators(Variant::AABB, operators);



	binder->get_builtin_binder().register_method(
		Variant::AABB,
		"abs",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			AABB *ptr = bind->getAABB();
			AABB ret = ptr->abs();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::AABB,
		"encloses",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			AABB *ptr = bind->getAABB();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::AABB, argv[0]), (JS_ThrowTypeError(ctx, "AABB expected for argument 0 of AABB.encloses")));
#endif
			const AABB &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getAABB();

			bool ret = ptr->encloses(arg0);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::AABB,
		"expand",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			AABB *ptr = bind->getAABB();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of AABB.expand")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			AABB ret = ptr->expand(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::AABB,
		"get_area",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			AABB *ptr = bind->getAABB();
			real_t ret = ptr->get_area();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::AABB,
		"get_endpoint",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			AABB *ptr = bind->getAABB();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of AABB.get_endpoint")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			Vector3 ret = ptr->get_endpoint(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::AABB,
		"get_longest_axis",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			AABB *ptr = bind->getAABB();
			Vector3 ret = ptr->get_longest_axis();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::AABB,
		"get_longest_axis_index",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			AABB *ptr = bind->getAABB();
			real_t ret = ptr->get_longest_axis_index();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::AABB,
		"get_longest_axis_size",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			AABB *ptr = bind->getAABB();
			real_t ret = ptr->get_longest_axis_size();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::AABB,
		"get_shortest_axis",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			AABB *ptr = bind->getAABB();
			Vector3 ret = ptr->get_shortest_axis();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::AABB,
		"get_shortest_axis_index",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			AABB *ptr = bind->getAABB();
			real_t ret = ptr->get_shortest_axis_index();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::AABB,
		"get_shortest_axis_size",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			AABB *ptr = bind->getAABB();
			real_t ret = ptr->get_shortest_axis_size();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::AABB,
		"get_support",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			AABB *ptr = bind->getAABB();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of AABB.get_support")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			Vector3 ret = ptr->get_support(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::AABB,
		"grow",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			AABB *ptr = bind->getAABB();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of AABB.grow")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			AABB ret = ptr->grow(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::AABB,
		"has_no_area",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			AABB *ptr = bind->getAABB();
			bool ret = ptr->has_no_area();
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::AABB,
		"has_no_surface",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			AABB *ptr = bind->getAABB();
			bool ret = ptr->has_no_surface();
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::AABB,
		"has_point",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			AABB *ptr = bind->getAABB();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of AABB.has_point")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			bool ret = ptr->has_point(arg0);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::AABB,
		"intersection",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			AABB *ptr = bind->getAABB();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::AABB, argv[0]), (JS_ThrowTypeError(ctx, "AABB expected for argument 0 of AABB.intersection")));
#endif
			const AABB &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getAABB();

			AABB ret = ptr->intersection(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::AABB,
		"intersects",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			AABB *ptr = bind->getAABB();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::AABB, argv[0]), (JS_ThrowTypeError(ctx, "AABB expected for argument 0 of AABB.intersects")));
#endif
			const AABB &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getAABB();

			bool ret = ptr->intersects(arg0);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::AABB,
		"intersects_plane",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			AABB *ptr = bind->getAABB();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::PLANE, argv[0]), (JS_ThrowTypeError(ctx, "Plane expected for argument 0 of AABB.intersects_plane")));
#endif
			const Plane &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getPlane();

			bool ret = ptr->intersects_plane(arg0);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::AABB,
		"intersects_segment",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			AABB *ptr = bind->getAABB();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of AABB.intersects_segment")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[1]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 1 of AABB.intersects_segment")));
#endif
			const Vector3 &arg1 = *(BINDING_DATA_FROM_JS(ctx, argv[1]))->getVector3();

			bool ret = ptr->intersects_segment(arg0, arg1);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::AABB,
		"is_equal_approx",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			AABB *ptr = bind->getAABB();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::AABB, argv[0]), (JS_ThrowTypeError(ctx, "AABB expected for argument 0 of AABB.is_equal_approx")));
#endif
			const AABB &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getAABB();

			bool ret = ptr->is_equal_approx(arg0);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::AABB,
		"merge",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			AABB *ptr = bind->getAABB();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::AABB, argv[0]), (JS_ThrowTypeError(ctx, "AABB expected for argument 0 of AABB.merge")));
#endif
			const AABB &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getAABB();

			AABB ret = ptr->merge(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
}

static JSValue Transform_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) {
	Transform tmp;
	
	if (argc == 4) {
#ifdef DEBUG_METHODS_ENABLED
		ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Transform(x_axis, y_axis, z_axis, origin)")));
		ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[1]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 1 of Transform(x_axis, y_axis, z_axis, origin)")));
		ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[2]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 2 of Transform(x_axis, y_axis, z_axis, origin)")));
		ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[3]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 3 of Transform(x_axis, y_axis, z_axis, origin)")));
#endif
		ECMAScriptGCHandler *param0 = BINDING_DATA_FROM_JS(ctx, argv[0]);
		ECMAScriptGCHandler *param1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
		ECMAScriptGCHandler *param2 = BINDING_DATA_FROM_JS(ctx, argv[2]);
		ECMAScriptGCHandler *param3 = BINDING_DATA_FROM_JS(ctx, argv[3]);

		tmp.basis.elements[0].operator=(*param0->getVector3());
		tmp.basis.elements[1].operator=(*param1->getVector3());
		tmp.basis.elements[2].operator=(*param2->getVector3());
		tmp.origin.operator=(*param3->getVector3());
	} else if (argc == 2) {
#ifdef DEBUG_METHODS_ENABLED
		ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::BASIS, argv[0]), (JS_ThrowTypeError(ctx, "Basis expected for argument 0 of Transform(basis, origin)")));
		ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[1]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 1 of Transform(basis, origin)")));
#endif
		ECMAScriptGCHandler *param0 = BINDING_DATA_FROM_JS(ctx, argv[0]);
		ECMAScriptGCHandler *param1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
		tmp.basis.operator=(*param0->getBasis());
		tmp.origin.operator=(*param1->getVector3());
	} else if (argc == 1) {
		if (ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0])) {
			if (bind->type == Variant::TRANSFORM) {
				tmp.operator=(*bind->getTransform());
			} else if (Variant::can_convert(bind->type, Variant::TRANSFORM)) {
				tmp.operator=(bind->get_value());
			}
		}
	}

	JSValue proto = JS_GetProperty(ctx, new_target, QuickJSBinder::JS_ATOM_prototype);
	JSValue obj = JS_NewObjectProtoClass(ctx, proto, QuickJSBinder::get_context_binder(ctx)->get_origin_class_id());
	QuickJSBuiltinBinder::bind_builtin_object(ctx, obj, Variant::TRANSFORM, &tmp);
	JS_FreeValue(ctx, proto);
	return obj;
	// return QuickJSBuiltinBinder::create_builtin_value(ctx, Variant::TRANSFORM, &tmp);
}

static void bind_Transform_properties(JSContext *ctx) {
	QuickJSBinder *binder = QuickJSBinder::get_context_binder(ctx);

	JSCFunctionMagic *getter = [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) -> JSValue {
		ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
		const Transform *ptr = bind->getTransform();
		switch (magic) {
			case 0:
				return QuickJSBuiltinBinder::new_object_from(ctx, ptr->basis);
			case 1:
				return QuickJSBuiltinBinder::new_object_from(ctx, ptr->origin);
		}
		return JS_UNDEFINED;
	};
	
	JSCFunctionMagic *setter = [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) -> JSValue {
		ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
		Transform *ptr = bind->getTransform();
		switch (magic) {
			case 0:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::BASIS, argv[0]), (JS_ThrowTypeError(ctx, "Basis expected for Transform.basis")));
#endif
				ptr->basis = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getBasis();
				break;
			case 1:
#ifdef DEBUG_METHODS_ENABLED
				ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for Transform.origin")));
#endif
				ptr->origin = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();
				break;
		}
		return JS_DupValue(ctx, argv[0]);
	};
	binder->get_builtin_binder().register_property(Variant::TRANSFORM, "basis", getter, setter, 0);
	binder->get_builtin_binder().register_property(Variant::TRANSFORM, "origin", getter, setter, 1);

		
	Vector<JSValue> operators;
	JSValue base_operators = JS_NewObject(ctx);

	JS_SetPropertyStr(ctx, base_operators, "==",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Transform *ptr = bind->getTransform();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::TRANSFORM, argv[1]), (JS_ThrowTypeError(ctx, "Transform expected for Transform.operator==")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Transform *target = bind1->getTransform();
			bool ret = ptr->operator==(*target);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		"equals",
		2)
	);
	
	JS_SetPropertyStr(ctx, base_operators, "*",
		JS_NewCFunction(ctx, [](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, argv[0]);
			Transform *ptr = bind->getTransform();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::TRANSFORM, argv[1]), (JS_ThrowTypeError(ctx, "Transform expected for Transform.operator*")));
#endif
			ECMAScriptGCHandler *bind1 = BINDING_DATA_FROM_JS(ctx, argv[1]);
			Transform *target = bind1->getTransform();
			Transform ret = ptr->operator*(*target);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		"multiply",
		2)
	);
	
	operators.push_back(base_operators);
	binder->get_builtin_binder().get_cross_type_operators(Variant::TRANSFORM, operators);
	binder->get_builtin_binder().register_operators(Variant::TRANSFORM, operators);

	binder->get_builtin_binder().register_constant(Variant::TRANSFORM, "IDENTITY", Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ));
	binder->get_builtin_binder().register_constant(Variant::TRANSFORM, "FLIP_X", Transform( -1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ));
	binder->get_builtin_binder().register_constant(Variant::TRANSFORM, "FLIP_Y", Transform( 1, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0 ));
	binder->get_builtin_binder().register_constant(Variant::TRANSFORM, "FLIP_Z", Transform( 1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0 ));


	binder->get_builtin_binder().register_method(
		Variant::TRANSFORM,
		"affine_inverse",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Transform *ptr = bind->getTransform();
			Transform ret = ptr->affine_inverse();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::TRANSFORM,
		"interpolate_with",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Transform *ptr = bind->getTransform();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::TRANSFORM, argv[0]), (JS_ThrowTypeError(ctx, "Transform expected for argument 0 of Transform.interpolate_with")));
#endif
			const Transform &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getTransform();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of Transform.interpolate_with")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			Transform ret = ptr->interpolate_with(arg0, arg1);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::TRANSFORM,
		"inverse",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Transform *ptr = bind->getTransform();
			Transform ret = ptr->inverse();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::TRANSFORM,
		"is_equal_approx",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Transform *ptr = bind->getTransform();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::TRANSFORM, argv[0]), (JS_ThrowTypeError(ctx, "Transform expected for argument 0 of Transform.is_equal_approx")));
#endif
			const Transform &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getTransform();

			bool ret = ptr->is_equal_approx(arg0);
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::TRANSFORM,
		"looking_at",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Transform *ptr = bind->getTransform();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Transform.looking_at")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[1]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 1 of Transform.looking_at")));
#endif
			const Vector3 &arg1 = *(BINDING_DATA_FROM_JS(ctx, argv[1]))->getVector3();

			Transform ret = ptr->looking_at(arg0, arg1);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::TRANSFORM,
		"orthonormalized",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Transform *ptr = bind->getTransform();
			Transform ret = ptr->orthonormalized();
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::TRANSFORM,
		"rotated",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Transform *ptr = bind->getTransform();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Transform.rotated")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of Transform.rotated")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			Transform ret = ptr->rotated(arg0, arg1);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::TRANSFORM,
		"scaled",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Transform *ptr = bind->getTransform();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Transform.scaled")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			Transform ret = ptr->scaled(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::TRANSFORM,
		"translated",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			Transform *ptr = bind->getTransform();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of Transform.translated")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			Transform ret = ptr->translated(arg0);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		1);
}

static JSValue PoolByteArray_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) {
	PoolByteArray tmp;
	
	if (argc == 1) {
		if (JS_IsArray(ctx, argv[0])) {
			Variant arr = QuickJSBinder::var_to_variant(ctx, argv[0]);
			tmp.operator=(arr);
		} else if (JS_IsArrayBuffer(argv[0])) {
			size_t size;
			uint8_t *buffer = JS_GetArrayBuffer(ctx, &size, argv[0]);
			if (size) {
				if (size % sizeof(uint8_t) != 0) {
					ERR_PRINT("Length of the ArrayBuffer does not match for PoolByteArray");
				}
				tmp.resize(size / sizeof(uint8_t));
				memcpy(tmp.write().ptr(), buffer, size / sizeof(uint8_t) * sizeof(uint8_t));
			}
		} else if (JS_IsDataView(argv[0])) {
			JSValue byte_length = JS_GetPropertyStr(ctx, argv[0], "byteLength");
			uint64_t length = QuickJSBinder::js_to_uint64(ctx, byte_length);
			JS_FreeValue(ctx, byte_length);

			JSValue byte_offset = JS_GetPropertyStr(ctx, argv[0], "byteOffset");
			uint64_t offset = QuickJSBinder::js_to_uint64(ctx, byte_offset);
			JS_FreeValue(ctx, byte_offset);

			size_t size;
			JSValue arraybuffer = JS_GetPropertyStr(ctx, argv[0], "buffer");
			uint8_t *buffer = JS_GetArrayBuffer(ctx, &size, arraybuffer);
			JS_FreeValue(ctx, arraybuffer);
			if (length) {
				tmp.resize(length / sizeof(uint8_t));
				memcpy(tmp.write().ptr(), buffer + offset, length / sizeof(uint8_t) * sizeof(uint8_t));
			}
		} else {
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(false, (JS_ThrowTypeError(ctx, "Array or ArrayBuffer expected for argument #0 of PoolByteArray(from)")));
#endif
		}
	}
	
	JSValue proto = JS_GetProperty(ctx, new_target, QuickJSBinder::JS_ATOM_prototype);
	JSValue obj = JS_NewObjectProtoClass(ctx, proto, QuickJSBinder::get_context_binder(ctx)->get_origin_class_id());
	QuickJSBuiltinBinder::bind_builtin_object(ctx, obj, Variant::POOL_BYTE_ARRAY, &tmp);
	JS_FreeValue(ctx, proto);
	return obj;
	// return QuickJSBuiltinBinder::create_builtin_value(ctx, Variant::POOL_BYTE_ARRAY, &tmp);
}

static void bind_PoolByteArray_properties(JSContext *ctx) {
	QuickJSBinder *binder = QuickJSBinder::get_context_binder(ctx);

	Vector<JSValue> operators;
	JSValue base_operators = JS_NewObject(ctx);

	operators.push_back(base_operators);
	binder->get_builtin_binder().get_cross_type_operators(Variant::POOL_BYTE_ARRAY, operators);
	binder->get_builtin_binder().register_operators(Variant::POOL_BYTE_ARRAY, operators);



	binder->get_builtin_binder().register_method(
		Variant::POOL_BYTE_ARRAY,
		"append",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolByteArray *ptr = bind->getPoolByteArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolByteArray.append")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			ptr->append(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_BYTE_ARRAY,
		"append_array",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolByteArray *ptr = bind->getPoolByteArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::POOL_BYTE_ARRAY, argv[0]), (JS_ThrowTypeError(ctx, "PoolByteArray expected for argument 0 of PoolByteArray.append_array")));
#endif
			const PoolByteArray &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getPoolByteArray();

			ptr->append_array(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_BYTE_ARRAY,
		"decompress_dynamic",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolByteArray *ptr = bind->getPoolByteArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolByteArray.decompress_dynamic")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of PoolByteArray.decompress_dynamic")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			PoolByteArray *decompressed = memnew(PoolByteArray);
			decompressed->resize(1024);

			Compression::Mode mode = (Compression::Mode)(arg1);

			int result = Compression::decompress_dynamic(decompressed, arg0, ptr->read().ptr(), ptr->size(), mode);

			if (result == OK) {
				return QuickJSBuiltinBinder::new_object_from(ctx, decompressed);
			} else {
				decompressed->resize(0);
				return JS_UNDEFINED;
			}
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::POOL_BYTE_ARRAY,
		"empty",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolByteArray *ptr = bind->getPoolByteArray();
			bool ret = ptr->empty();
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::POOL_BYTE_ARRAY,
		"insert",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolByteArray *ptr = bind->getPoolByteArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolByteArray.insert")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of PoolByteArray.insert")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			real_t ret = ptr->insert(arg0, arg1);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::POOL_BYTE_ARRAY,
		"invert",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolByteArray *ptr = bind->getPoolByteArray();
			ptr->invert();
			return JS_UNDEFINED;
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::POOL_BYTE_ARRAY,
		"push_back",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolByteArray *ptr = bind->getPoolByteArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolByteArray.push_back")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			ptr->push_back(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_BYTE_ARRAY,
		"remove",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolByteArray *ptr = bind->getPoolByteArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolByteArray.remove")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			ptr->remove(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_BYTE_ARRAY,
		"resize",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolByteArray *ptr = bind->getPoolByteArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolByteArray.resize")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			ptr->resize(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_BYTE_ARRAY,
		"set",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolByteArray *ptr = bind->getPoolByteArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolByteArray.set")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of PoolByteArray.set")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			ptr->set(arg0, arg1);
			return JS_UNDEFINED;
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::POOL_BYTE_ARRAY,
		"size",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolByteArray *ptr = bind->getPoolByteArray();
			real_t ret = ptr->size();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::POOL_BYTE_ARRAY,
		"subarray",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolByteArray *ptr = bind->getPoolByteArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolByteArray.subarray")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of PoolByteArray.subarray")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			PoolByteArray ret = ptr->subarray(arg0, arg1);
			return QuickJSBuiltinBinder::new_object_from(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::POOL_BYTE_ARRAY,
		"get",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolByteArray *ptr = bind->getPoolByteArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolByteArray.get")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			Variant ret = ptr->operator[](arg0);
			return QuickJSBinder::variant_to_var(ctx, ret);
		},
		1);
}

static JSValue PoolIntArray_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) {
	PoolIntArray tmp;
	
	if (argc == 1) {
		if (JS_IsArray(ctx, argv[0])) {
			Variant arr = QuickJSBinder::var_to_variant(ctx, argv[0]);
			tmp.operator=(arr);
		} else if (JS_IsArrayBuffer(argv[0])) {
			size_t size;
			uint8_t *buffer = JS_GetArrayBuffer(ctx, &size, argv[0]);
			if (size) {
				if (size % sizeof(int) != 0) {
					ERR_PRINT("Length of the ArrayBuffer does not match for PoolIntArray");
				}
				tmp.resize(size / sizeof(int));
				memcpy(tmp.write().ptr(), buffer, size / sizeof(int) * sizeof(int));
			}
		} else if (JS_IsDataView(argv[0])) {
			JSValue byte_length = JS_GetPropertyStr(ctx, argv[0], "byteLength");
			uint64_t length = QuickJSBinder::js_to_uint64(ctx, byte_length);
			JS_FreeValue(ctx, byte_length);

			JSValue byte_offset = JS_GetPropertyStr(ctx, argv[0], "byteOffset");
			uint64_t offset = QuickJSBinder::js_to_uint64(ctx, byte_offset);
			JS_FreeValue(ctx, byte_offset);

			size_t size;
			JSValue arraybuffer = JS_GetPropertyStr(ctx, argv[0], "buffer");
			uint8_t *buffer = JS_GetArrayBuffer(ctx, &size, arraybuffer);
			JS_FreeValue(ctx, arraybuffer);
			if (length) {
				tmp.resize(length / sizeof(int));
				memcpy(tmp.write().ptr(), buffer + offset, length / sizeof(int) * sizeof(int));
			}
		} else {
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(false, (JS_ThrowTypeError(ctx, "Array or ArrayBuffer expected for argument #0 of PoolIntArray(from)")));
#endif
		}
	}
	
	JSValue proto = JS_GetProperty(ctx, new_target, QuickJSBinder::JS_ATOM_prototype);
	JSValue obj = JS_NewObjectProtoClass(ctx, proto, QuickJSBinder::get_context_binder(ctx)->get_origin_class_id());
	QuickJSBuiltinBinder::bind_builtin_object(ctx, obj, Variant::POOL_INT_ARRAY, &tmp);
	JS_FreeValue(ctx, proto);
	return obj;
	// return QuickJSBuiltinBinder::create_builtin_value(ctx, Variant::POOL_INT_ARRAY, &tmp);
}

static void bind_PoolIntArray_properties(JSContext *ctx) {
	QuickJSBinder *binder = QuickJSBinder::get_context_binder(ctx);

	Vector<JSValue> operators;
	JSValue base_operators = JS_NewObject(ctx);

	operators.push_back(base_operators);
	binder->get_builtin_binder().get_cross_type_operators(Variant::POOL_INT_ARRAY, operators);
	binder->get_builtin_binder().register_operators(Variant::POOL_INT_ARRAY, operators);



	binder->get_builtin_binder().register_method(
		Variant::POOL_INT_ARRAY,
		"append",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolIntArray *ptr = bind->getPoolIntArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolIntArray.append")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			ptr->append(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_INT_ARRAY,
		"append_array",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolIntArray *ptr = bind->getPoolIntArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::POOL_INT_ARRAY, argv[0]), (JS_ThrowTypeError(ctx, "PoolIntArray expected for argument 0 of PoolIntArray.append_array")));
#endif
			const PoolIntArray &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getPoolIntArray();

			ptr->append_array(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_INT_ARRAY,
		"empty",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolIntArray *ptr = bind->getPoolIntArray();
			bool ret = ptr->empty();
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::POOL_INT_ARRAY,
		"insert",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolIntArray *ptr = bind->getPoolIntArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolIntArray.insert")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of PoolIntArray.insert")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			real_t ret = ptr->insert(arg0, arg1);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::POOL_INT_ARRAY,
		"invert",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolIntArray *ptr = bind->getPoolIntArray();
			ptr->invert();
			return JS_UNDEFINED;
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::POOL_INT_ARRAY,
		"push_back",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolIntArray *ptr = bind->getPoolIntArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolIntArray.push_back")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			ptr->push_back(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_INT_ARRAY,
		"remove",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolIntArray *ptr = bind->getPoolIntArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolIntArray.remove")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			ptr->remove(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_INT_ARRAY,
		"resize",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolIntArray *ptr = bind->getPoolIntArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolIntArray.resize")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			ptr->resize(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_INT_ARRAY,
		"set",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolIntArray *ptr = bind->getPoolIntArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolIntArray.set")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of PoolIntArray.set")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			ptr->set(arg0, arg1);
			return JS_UNDEFINED;
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::POOL_INT_ARRAY,
		"size",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolIntArray *ptr = bind->getPoolIntArray();
			real_t ret = ptr->size();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::POOL_INT_ARRAY,
		"get",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolIntArray *ptr = bind->getPoolIntArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolIntArray.get")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			Variant ret = ptr->operator[](arg0);
			return QuickJSBinder::variant_to_var(ctx, ret);
		},
		1);
}

static JSValue PoolRealArray_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) {
	PoolRealArray tmp;
	
	if (argc == 1) {
		if (JS_IsArray(ctx, argv[0])) {
			Variant arr = QuickJSBinder::var_to_variant(ctx, argv[0]);
			tmp.operator=(arr);
		} else if (JS_IsArrayBuffer(argv[0])) {
			size_t size;
			uint8_t *buffer = JS_GetArrayBuffer(ctx, &size, argv[0]);
			if (size) {
				if (size % sizeof(real_t) != 0) {
					ERR_PRINT("Length of the ArrayBuffer does not match for PoolRealArray");
				}
				tmp.resize(size / sizeof(real_t));
				memcpy(tmp.write().ptr(), buffer, size / sizeof(real_t) * sizeof(real_t));
			}
		} else if (JS_IsDataView(argv[0])) {
			JSValue byte_length = JS_GetPropertyStr(ctx, argv[0], "byteLength");
			uint64_t length = QuickJSBinder::js_to_uint64(ctx, byte_length);
			JS_FreeValue(ctx, byte_length);

			JSValue byte_offset = JS_GetPropertyStr(ctx, argv[0], "byteOffset");
			uint64_t offset = QuickJSBinder::js_to_uint64(ctx, byte_offset);
			JS_FreeValue(ctx, byte_offset);

			size_t size;
			JSValue arraybuffer = JS_GetPropertyStr(ctx, argv[0], "buffer");
			uint8_t *buffer = JS_GetArrayBuffer(ctx, &size, arraybuffer);
			JS_FreeValue(ctx, arraybuffer);
			if (length) {
				tmp.resize(length / sizeof(real_t));
				memcpy(tmp.write().ptr(), buffer + offset, length / sizeof(real_t) * sizeof(real_t));
			}
		} else {
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(false, (JS_ThrowTypeError(ctx, "Array or ArrayBuffer expected for argument #0 of PoolRealArray(from)")));
#endif
		}
	}
	
	JSValue proto = JS_GetProperty(ctx, new_target, QuickJSBinder::JS_ATOM_prototype);
	JSValue obj = JS_NewObjectProtoClass(ctx, proto, QuickJSBinder::get_context_binder(ctx)->get_origin_class_id());
	QuickJSBuiltinBinder::bind_builtin_object(ctx, obj, Variant::POOL_REAL_ARRAY, &tmp);
	JS_FreeValue(ctx, proto);
	return obj;
	// return QuickJSBuiltinBinder::create_builtin_value(ctx, Variant::POOL_REAL_ARRAY, &tmp);
}

static void bind_PoolRealArray_properties(JSContext *ctx) {
	QuickJSBinder *binder = QuickJSBinder::get_context_binder(ctx);

	Vector<JSValue> operators;
	JSValue base_operators = JS_NewObject(ctx);

	operators.push_back(base_operators);
	binder->get_builtin_binder().get_cross_type_operators(Variant::POOL_REAL_ARRAY, operators);
	binder->get_builtin_binder().register_operators(Variant::POOL_REAL_ARRAY, operators);



	binder->get_builtin_binder().register_method(
		Variant::POOL_REAL_ARRAY,
		"append",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolRealArray *ptr = bind->getPoolRealArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolRealArray.append")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			ptr->append(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_REAL_ARRAY,
		"append_array",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolRealArray *ptr = bind->getPoolRealArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::POOL_REAL_ARRAY, argv[0]), (JS_ThrowTypeError(ctx, "PoolRealArray expected for argument 0 of PoolRealArray.append_array")));
#endif
			const PoolRealArray &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getPoolRealArray();

			ptr->append_array(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_REAL_ARRAY,
		"empty",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolRealArray *ptr = bind->getPoolRealArray();
			bool ret = ptr->empty();
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::POOL_REAL_ARRAY,
		"insert",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolRealArray *ptr = bind->getPoolRealArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolRealArray.insert")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of PoolRealArray.insert")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			real_t ret = ptr->insert(arg0, arg1);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::POOL_REAL_ARRAY,
		"invert",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolRealArray *ptr = bind->getPoolRealArray();
			ptr->invert();
			return JS_UNDEFINED;
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::POOL_REAL_ARRAY,
		"push_back",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolRealArray *ptr = bind->getPoolRealArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolRealArray.push_back")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			ptr->push_back(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_REAL_ARRAY,
		"remove",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolRealArray *ptr = bind->getPoolRealArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolRealArray.remove")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			ptr->remove(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_REAL_ARRAY,
		"resize",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolRealArray *ptr = bind->getPoolRealArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolRealArray.resize")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			ptr->resize(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_REAL_ARRAY,
		"set",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolRealArray *ptr = bind->getPoolRealArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolRealArray.set")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[1]), (JS_ThrowTypeError(ctx, "number expected for argument 1 of PoolRealArray.set")));
#endif
			const real_t &arg1 = QuickJSBinder::js_to_number(ctx, argv[1]);

			ptr->set(arg0, arg1);
			return JS_UNDEFINED;
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::POOL_REAL_ARRAY,
		"size",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolRealArray *ptr = bind->getPoolRealArray();
			real_t ret = ptr->size();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::POOL_REAL_ARRAY,
		"get",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolRealArray *ptr = bind->getPoolRealArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolRealArray.get")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			Variant ret = ptr->operator[](arg0);
			return QuickJSBinder::variant_to_var(ctx, ret);
		},
		1);
}

static JSValue PoolStringArray_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) {
	PoolStringArray tmp;
	
	if (argc == 1) {
#ifdef DEBUG_METHODS_ENABLED
		ERR_FAIL_COND_V(!JS_IsArray(ctx, argv[0]), (JS_ThrowTypeError(ctx, "Array expected for argument #0 of PoolStringArray(from)")));
#endif
		Variant arr = QuickJSBinder::var_to_variant(ctx, argv[0]);
		tmp.operator=(arr);
	}
	
	JSValue proto = JS_GetProperty(ctx, new_target, QuickJSBinder::JS_ATOM_prototype);
	JSValue obj = JS_NewObjectProtoClass(ctx, proto, QuickJSBinder::get_context_binder(ctx)->get_origin_class_id());
	QuickJSBuiltinBinder::bind_builtin_object(ctx, obj, Variant::POOL_STRING_ARRAY, &tmp);
	JS_FreeValue(ctx, proto);
	return obj;
	// return QuickJSBuiltinBinder::create_builtin_value(ctx, Variant::POOL_STRING_ARRAY, &tmp);
}

static void bind_PoolStringArray_properties(JSContext *ctx) {
	QuickJSBinder *binder = QuickJSBinder::get_context_binder(ctx);

	Vector<JSValue> operators;
	JSValue base_operators = JS_NewObject(ctx);

	operators.push_back(base_operators);
	binder->get_builtin_binder().get_cross_type_operators(Variant::POOL_STRING_ARRAY, operators);
	binder->get_builtin_binder().register_operators(Variant::POOL_STRING_ARRAY, operators);



	binder->get_builtin_binder().register_method(
		Variant::POOL_STRING_ARRAY,
		"append",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolStringArray *ptr = bind->getPoolStringArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::STRING, argv[0]), (JS_ThrowTypeError(ctx, "string expected for argument 0 of PoolStringArray.append")));
#endif
			const String &arg0 = QuickJSBinder::js_to_string(ctx, argv[0]);

			ptr->append(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_STRING_ARRAY,
		"append_array",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolStringArray *ptr = bind->getPoolStringArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::POOL_STRING_ARRAY, argv[0]), (JS_ThrowTypeError(ctx, "PoolStringArray expected for argument 0 of PoolStringArray.append_array")));
#endif
			const PoolStringArray &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getPoolStringArray();

			ptr->append_array(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_STRING_ARRAY,
		"empty",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolStringArray *ptr = bind->getPoolStringArray();
			bool ret = ptr->empty();
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::POOL_STRING_ARRAY,
		"insert",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolStringArray *ptr = bind->getPoolStringArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolStringArray.insert")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::STRING, argv[1]), (JS_ThrowTypeError(ctx, "string expected for argument 1 of PoolStringArray.insert")));
#endif
			const String &arg1 = QuickJSBinder::js_to_string(ctx, argv[1]);

			real_t ret = ptr->insert(arg0, arg1);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::POOL_STRING_ARRAY,
		"invert",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolStringArray *ptr = bind->getPoolStringArray();
			ptr->invert();
			return JS_UNDEFINED;
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::POOL_STRING_ARRAY,
		"join",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolStringArray *ptr = bind->getPoolStringArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::STRING, argv[0]), (JS_ThrowTypeError(ctx, "string expected for argument 0 of PoolStringArray.join")));
#endif
			const String &arg0 = QuickJSBinder::js_to_string(ctx, argv[0]);

			String ret = ptr->join(arg0);
			return QuickJSBinder::to_js_string(ctx, ret);
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_STRING_ARRAY,
		"push_back",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolStringArray *ptr = bind->getPoolStringArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::STRING, argv[0]), (JS_ThrowTypeError(ctx, "string expected for argument 0 of PoolStringArray.push_back")));
#endif
			const String &arg0 = QuickJSBinder::js_to_string(ctx, argv[0]);

			ptr->push_back(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_STRING_ARRAY,
		"remove",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolStringArray *ptr = bind->getPoolStringArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolStringArray.remove")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			ptr->remove(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_STRING_ARRAY,
		"resize",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolStringArray *ptr = bind->getPoolStringArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolStringArray.resize")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			ptr->resize(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_STRING_ARRAY,
		"set",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolStringArray *ptr = bind->getPoolStringArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolStringArray.set")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::STRING, argv[1]), (JS_ThrowTypeError(ctx, "string expected for argument 1 of PoolStringArray.set")));
#endif
			const String &arg1 = QuickJSBinder::js_to_string(ctx, argv[1]);

			ptr->set(arg0, arg1);
			return JS_UNDEFINED;
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::POOL_STRING_ARRAY,
		"size",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolStringArray *ptr = bind->getPoolStringArray();
			real_t ret = ptr->size();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::POOL_STRING_ARRAY,
		"get",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolStringArray *ptr = bind->getPoolStringArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolStringArray.get")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			Variant ret = ptr->operator[](arg0);
			return QuickJSBinder::variant_to_var(ctx, ret);
		},
		1);
}

static JSValue PoolVector2Array_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) {
	PoolVector2Array tmp;
	
	if (argc == 1) {
		if (JS_IsArray(ctx, argv[0])) {
			Variant arr = QuickJSBinder::var_to_variant(ctx, argv[0]);
			tmp.operator=(arr);
		} else if (JS_IsArrayBuffer(argv[0])) {
			size_t size;
			uint8_t *buffer = JS_GetArrayBuffer(ctx, &size, argv[0]);
			if (size) {
				if (size % sizeof(Vector2) != 0) {
					ERR_PRINT("Length of the ArrayBuffer does not match for PoolVector2Array");
				}
				tmp.resize(size / sizeof(Vector2));
				memcpy(tmp.write().ptr(), buffer, size / sizeof(Vector2) * sizeof(Vector2));
			}
		} else if (JS_IsDataView(argv[0])) {
			JSValue byte_length = JS_GetPropertyStr(ctx, argv[0], "byteLength");
			uint64_t length = QuickJSBinder::js_to_uint64(ctx, byte_length);
			JS_FreeValue(ctx, byte_length);

			JSValue byte_offset = JS_GetPropertyStr(ctx, argv[0], "byteOffset");
			uint64_t offset = QuickJSBinder::js_to_uint64(ctx, byte_offset);
			JS_FreeValue(ctx, byte_offset);

			size_t size;
			JSValue arraybuffer = JS_GetPropertyStr(ctx, argv[0], "buffer");
			uint8_t *buffer = JS_GetArrayBuffer(ctx, &size, arraybuffer);
			JS_FreeValue(ctx, arraybuffer);
			if (length) {
				tmp.resize(length / sizeof(Vector2));
				memcpy(tmp.write().ptr(), buffer + offset, length / sizeof(Vector2) * sizeof(Vector2));
			}
		} else {
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(false, (JS_ThrowTypeError(ctx, "Array or ArrayBuffer expected for argument #0 of PoolVector2Array(from)")));
#endif
		}
	}
	
	JSValue proto = JS_GetProperty(ctx, new_target, QuickJSBinder::JS_ATOM_prototype);
	JSValue obj = JS_NewObjectProtoClass(ctx, proto, QuickJSBinder::get_context_binder(ctx)->get_origin_class_id());
	QuickJSBuiltinBinder::bind_builtin_object(ctx, obj, Variant::POOL_VECTOR2_ARRAY, &tmp);
	JS_FreeValue(ctx, proto);
	return obj;
	// return QuickJSBuiltinBinder::create_builtin_value(ctx, Variant::POOL_VECTOR2_ARRAY, &tmp);
}

static void bind_PoolVector2Array_properties(JSContext *ctx) {
	QuickJSBinder *binder = QuickJSBinder::get_context_binder(ctx);

	Vector<JSValue> operators;
	JSValue base_operators = JS_NewObject(ctx);

	operators.push_back(base_operators);
	binder->get_builtin_binder().get_cross_type_operators(Variant::POOL_VECTOR2_ARRAY, operators);
	binder->get_builtin_binder().register_operators(Variant::POOL_VECTOR2_ARRAY, operators);



	binder->get_builtin_binder().register_method(
		Variant::POOL_VECTOR2_ARRAY,
		"append",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolVector2Array *ptr = bind->getPoolVector2Array();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of PoolVector2Array.append")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

			ptr->append(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_VECTOR2_ARRAY,
		"append_array",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolVector2Array *ptr = bind->getPoolVector2Array();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::POOL_VECTOR2_ARRAY, argv[0]), (JS_ThrowTypeError(ctx, "PoolVector2Array expected for argument 0 of PoolVector2Array.append_array")));
#endif
			const PoolVector2Array &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getPoolVector2Array();

			ptr->append_array(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_VECTOR2_ARRAY,
		"empty",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolVector2Array *ptr = bind->getPoolVector2Array();
			bool ret = ptr->empty();
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::POOL_VECTOR2_ARRAY,
		"insert",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolVector2Array *ptr = bind->getPoolVector2Array();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolVector2Array.insert")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[1]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 1 of PoolVector2Array.insert")));
#endif
			const Vector2 &arg1 = *(BINDING_DATA_FROM_JS(ctx, argv[1]))->getVector2();

			real_t ret = ptr->insert(arg0, arg1);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::POOL_VECTOR2_ARRAY,
		"invert",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolVector2Array *ptr = bind->getPoolVector2Array();
			ptr->invert();
			return JS_UNDEFINED;
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::POOL_VECTOR2_ARRAY,
		"push_back",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolVector2Array *ptr = bind->getPoolVector2Array();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[0]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 0 of PoolVector2Array.push_back")));
#endif
			const Vector2 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector2();

			ptr->push_back(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_VECTOR2_ARRAY,
		"remove",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolVector2Array *ptr = bind->getPoolVector2Array();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolVector2Array.remove")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			ptr->remove(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_VECTOR2_ARRAY,
		"resize",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolVector2Array *ptr = bind->getPoolVector2Array();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolVector2Array.resize")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			ptr->resize(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_VECTOR2_ARRAY,
		"set",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolVector2Array *ptr = bind->getPoolVector2Array();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolVector2Array.set")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR2, argv[1]), (JS_ThrowTypeError(ctx, "Vector2 expected for argument 1 of PoolVector2Array.set")));
#endif
			const Vector2 &arg1 = *(BINDING_DATA_FROM_JS(ctx, argv[1]))->getVector2();

			ptr->set(arg0, arg1);
			return JS_UNDEFINED;
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::POOL_VECTOR2_ARRAY,
		"size",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolVector2Array *ptr = bind->getPoolVector2Array();
			real_t ret = ptr->size();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::POOL_VECTOR2_ARRAY,
		"get",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolVector2Array *ptr = bind->getPoolVector2Array();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolVector2Array.get")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			Variant ret = ptr->operator[](arg0);
			return QuickJSBinder::variant_to_var(ctx, ret);
		},
		1);
}

static JSValue PoolVector3Array_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) {
	PoolVector3Array tmp;
	
	if (argc == 1) {
		if (JS_IsArray(ctx, argv[0])) {
			Variant arr = QuickJSBinder::var_to_variant(ctx, argv[0]);
			tmp.operator=(arr);
		} else if (JS_IsArrayBuffer(argv[0])) {
			size_t size;
			uint8_t *buffer = JS_GetArrayBuffer(ctx, &size, argv[0]);
			if (size) {
				if (size % sizeof(Vector3) != 0) {
					ERR_PRINT("Length of the ArrayBuffer does not match for PoolVector3Array");
				}
				tmp.resize(size / sizeof(Vector3));
				memcpy(tmp.write().ptr(), buffer, size / sizeof(Vector3) * sizeof(Vector3));
			}
		} else if (JS_IsDataView(argv[0])) {
			JSValue byte_length = JS_GetPropertyStr(ctx, argv[0], "byteLength");
			uint64_t length = QuickJSBinder::js_to_uint64(ctx, byte_length);
			JS_FreeValue(ctx, byte_length);

			JSValue byte_offset = JS_GetPropertyStr(ctx, argv[0], "byteOffset");
			uint64_t offset = QuickJSBinder::js_to_uint64(ctx, byte_offset);
			JS_FreeValue(ctx, byte_offset);

			size_t size;
			JSValue arraybuffer = JS_GetPropertyStr(ctx, argv[0], "buffer");
			uint8_t *buffer = JS_GetArrayBuffer(ctx, &size, arraybuffer);
			JS_FreeValue(ctx, arraybuffer);
			if (length) {
				tmp.resize(length / sizeof(Vector3));
				memcpy(tmp.write().ptr(), buffer + offset, length / sizeof(Vector3) * sizeof(Vector3));
			}
		} else {
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(false, (JS_ThrowTypeError(ctx, "Array or ArrayBuffer expected for argument #0 of PoolVector3Array(from)")));
#endif
		}
	}
	
	JSValue proto = JS_GetProperty(ctx, new_target, QuickJSBinder::JS_ATOM_prototype);
	JSValue obj = JS_NewObjectProtoClass(ctx, proto, QuickJSBinder::get_context_binder(ctx)->get_origin_class_id());
	QuickJSBuiltinBinder::bind_builtin_object(ctx, obj, Variant::POOL_VECTOR3_ARRAY, &tmp);
	JS_FreeValue(ctx, proto);
	return obj;
	// return QuickJSBuiltinBinder::create_builtin_value(ctx, Variant::POOL_VECTOR3_ARRAY, &tmp);
}

static void bind_PoolVector3Array_properties(JSContext *ctx) {
	QuickJSBinder *binder = QuickJSBinder::get_context_binder(ctx);

	Vector<JSValue> operators;
	JSValue base_operators = JS_NewObject(ctx);

	operators.push_back(base_operators);
	binder->get_builtin_binder().get_cross_type_operators(Variant::POOL_VECTOR3_ARRAY, operators);
	binder->get_builtin_binder().register_operators(Variant::POOL_VECTOR3_ARRAY, operators);



	binder->get_builtin_binder().register_method(
		Variant::POOL_VECTOR3_ARRAY,
		"append",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolVector3Array *ptr = bind->getPoolVector3Array();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of PoolVector3Array.append")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			ptr->append(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_VECTOR3_ARRAY,
		"append_array",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolVector3Array *ptr = bind->getPoolVector3Array();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::POOL_VECTOR3_ARRAY, argv[0]), (JS_ThrowTypeError(ctx, "PoolVector3Array expected for argument 0 of PoolVector3Array.append_array")));
#endif
			const PoolVector3Array &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getPoolVector3Array();

			ptr->append_array(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_VECTOR3_ARRAY,
		"empty",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolVector3Array *ptr = bind->getPoolVector3Array();
			bool ret = ptr->empty();
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::POOL_VECTOR3_ARRAY,
		"insert",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolVector3Array *ptr = bind->getPoolVector3Array();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolVector3Array.insert")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[1]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 1 of PoolVector3Array.insert")));
#endif
			const Vector3 &arg1 = *(BINDING_DATA_FROM_JS(ctx, argv[1]))->getVector3();

			real_t ret = ptr->insert(arg0, arg1);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::POOL_VECTOR3_ARRAY,
		"invert",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolVector3Array *ptr = bind->getPoolVector3Array();
			ptr->invert();
			return JS_UNDEFINED;
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::POOL_VECTOR3_ARRAY,
		"push_back",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolVector3Array *ptr = bind->getPoolVector3Array();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[0]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 0 of PoolVector3Array.push_back")));
#endif
			const Vector3 &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getVector3();

			ptr->push_back(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_VECTOR3_ARRAY,
		"remove",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolVector3Array *ptr = bind->getPoolVector3Array();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolVector3Array.remove")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			ptr->remove(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_VECTOR3_ARRAY,
		"resize",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolVector3Array *ptr = bind->getPoolVector3Array();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolVector3Array.resize")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			ptr->resize(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_VECTOR3_ARRAY,
		"set",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolVector3Array *ptr = bind->getPoolVector3Array();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolVector3Array.set")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::VECTOR3, argv[1]), (JS_ThrowTypeError(ctx, "Vector3 expected for argument 1 of PoolVector3Array.set")));
#endif
			const Vector3 &arg1 = *(BINDING_DATA_FROM_JS(ctx, argv[1]))->getVector3();

			ptr->set(arg0, arg1);
			return JS_UNDEFINED;
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::POOL_VECTOR3_ARRAY,
		"size",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolVector3Array *ptr = bind->getPoolVector3Array();
			real_t ret = ptr->size();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::POOL_VECTOR3_ARRAY,
		"get",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolVector3Array *ptr = bind->getPoolVector3Array();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolVector3Array.get")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			Variant ret = ptr->operator[](arg0);
			return QuickJSBinder::variant_to_var(ctx, ret);
		},
		1);
}

static JSValue PoolColorArray_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv) {
	PoolColorArray tmp;
	
	if (argc == 1) {
		if (JS_IsArray(ctx, argv[0])) {
			Variant arr = QuickJSBinder::var_to_variant(ctx, argv[0]);
			tmp.operator=(arr);
		} else if (JS_IsArrayBuffer(argv[0])) {
			size_t size;
			uint8_t *buffer = JS_GetArrayBuffer(ctx, &size, argv[0]);
			if (size) {
				if (size % sizeof(Color) != 0) {
					ERR_PRINT("Length of the ArrayBuffer does not match for PoolColorArray");
				}
				tmp.resize(size / sizeof(Color));
				memcpy(tmp.write().ptr(), buffer, size / sizeof(Color) * sizeof(Color));
			}
		} else if (JS_IsDataView(argv[0])) {
			JSValue byte_length = JS_GetPropertyStr(ctx, argv[0], "byteLength");
			uint64_t length = QuickJSBinder::js_to_uint64(ctx, byte_length);
			JS_FreeValue(ctx, byte_length);

			JSValue byte_offset = JS_GetPropertyStr(ctx, argv[0], "byteOffset");
			uint64_t offset = QuickJSBinder::js_to_uint64(ctx, byte_offset);
			JS_FreeValue(ctx, byte_offset);

			size_t size;
			JSValue arraybuffer = JS_GetPropertyStr(ctx, argv[0], "buffer");
			uint8_t *buffer = JS_GetArrayBuffer(ctx, &size, arraybuffer);
			JS_FreeValue(ctx, arraybuffer);
			if (length) {
				tmp.resize(length / sizeof(Color));
				memcpy(tmp.write().ptr(), buffer + offset, length / sizeof(Color) * sizeof(Color));
			}
		} else {
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(false, (JS_ThrowTypeError(ctx, "Array or ArrayBuffer expected for argument #0 of PoolColorArray(from)")));
#endif
		}
	}
	
	JSValue proto = JS_GetProperty(ctx, new_target, QuickJSBinder::JS_ATOM_prototype);
	JSValue obj = JS_NewObjectProtoClass(ctx, proto, QuickJSBinder::get_context_binder(ctx)->get_origin_class_id());
	QuickJSBuiltinBinder::bind_builtin_object(ctx, obj, Variant::POOL_COLOR_ARRAY, &tmp);
	JS_FreeValue(ctx, proto);
	return obj;
	// return QuickJSBuiltinBinder::create_builtin_value(ctx, Variant::POOL_COLOR_ARRAY, &tmp);
}

static void bind_PoolColorArray_properties(JSContext *ctx) {
	QuickJSBinder *binder = QuickJSBinder::get_context_binder(ctx);

	Vector<JSValue> operators;
	JSValue base_operators = JS_NewObject(ctx);

	operators.push_back(base_operators);
	binder->get_builtin_binder().get_cross_type_operators(Variant::POOL_COLOR_ARRAY, operators);
	binder->get_builtin_binder().register_operators(Variant::POOL_COLOR_ARRAY, operators);



	binder->get_builtin_binder().register_method(
		Variant::POOL_COLOR_ARRAY,
		"append",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolColorArray *ptr = bind->getPoolColorArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::COLOR, argv[0]), (JS_ThrowTypeError(ctx, "Color expected for argument 0 of PoolColorArray.append")));
#endif
			const Color &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getColor();

			ptr->append(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_COLOR_ARRAY,
		"append_array",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolColorArray *ptr = bind->getPoolColorArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::POOL_COLOR_ARRAY, argv[0]), (JS_ThrowTypeError(ctx, "PoolColorArray expected for argument 0 of PoolColorArray.append_array")));
#endif
			const PoolColorArray &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getPoolColorArray();

			ptr->append_array(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_COLOR_ARRAY,
		"empty",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolColorArray *ptr = bind->getPoolColorArray();
			bool ret = ptr->empty();
			return QuickJSBinder::to_js_bool(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::POOL_COLOR_ARRAY,
		"insert",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolColorArray *ptr = bind->getPoolColorArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolColorArray.insert")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::COLOR, argv[1]), (JS_ThrowTypeError(ctx, "Color expected for argument 1 of PoolColorArray.insert")));
#endif
			const Color &arg1 = *(BINDING_DATA_FROM_JS(ctx, argv[1]))->getColor();

			real_t ret = ptr->insert(arg0, arg1);
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::POOL_COLOR_ARRAY,
		"invert",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolColorArray *ptr = bind->getPoolColorArray();
			ptr->invert();
			return JS_UNDEFINED;
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::POOL_COLOR_ARRAY,
		"push_back",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolColorArray *ptr = bind->getPoolColorArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::COLOR, argv[0]), (JS_ThrowTypeError(ctx, "Color expected for argument 0 of PoolColorArray.push_back")));
#endif
			const Color &arg0 = *(BINDING_DATA_FROM_JS(ctx, argv[0]))->getColor();

			ptr->push_back(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_COLOR_ARRAY,
		"remove",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolColorArray *ptr = bind->getPoolColorArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolColorArray.remove")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			ptr->remove(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_COLOR_ARRAY,
		"resize",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolColorArray *ptr = bind->getPoolColorArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolColorArray.resize")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			ptr->resize(arg0);
			return JS_UNDEFINED;
		},
		1);
	binder->get_builtin_binder().register_method(
		Variant::POOL_COLOR_ARRAY,
		"set",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolColorArray *ptr = bind->getPoolColorArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolColorArray.set")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::COLOR, argv[1]), (JS_ThrowTypeError(ctx, "Color expected for argument 1 of PoolColorArray.set")));
#endif
			const Color &arg1 = *(BINDING_DATA_FROM_JS(ctx, argv[1]))->getColor();

			ptr->set(arg0, arg1);
			return JS_UNDEFINED;
		},
		2);
	binder->get_builtin_binder().register_method(
		Variant::POOL_COLOR_ARRAY,
		"size",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolColorArray *ptr = bind->getPoolColorArray();
			real_t ret = ptr->size();
			return QuickJSBinder::to_js_number(ctx, ret);
		},
		0);
	binder->get_builtin_binder().register_method(
		Variant::POOL_COLOR_ARRAY,
		"get",
		[](JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
			ECMAScriptGCHandler *bind = BINDING_DATA_FROM_JS(ctx, this_val);
			PoolColorArray *ptr = bind->getPoolColorArray();
#ifdef DEBUG_METHODS_ENABLED
			ERR_FAIL_COND_V(!QuickJSBinder::validate_type(ctx, Variant::REAL, argv[0]), (JS_ThrowTypeError(ctx, "number expected for argument 0 of PoolColorArray.get")));
#endif
			const real_t &arg0 = QuickJSBinder::js_to_number(ctx, argv[0]);

			Variant ret = ptr->operator[](arg0);
			return QuickJSBinder::variant_to_var(ctx, ret);
		},
		1);
}

